JAVA - 쓰레드

쓰레드 관련 프로그래밍 자체는 그리 어렵지 않다.

하지만 쓰레드에 대한 이해 없이는 프로그래밍이 불가능 하다.

따라서 쓰레드에 대해 먼저 알아보자


프로그램의 실행 주체는 운영체제이다.

프로그램의 실행이 요청되어지면

아래와 같은 형태로 메모리 공간이 할당된다.



이 메모리를 기반으로 프로그램이 실행된다.


이렇듯 할당된 메모리 공간을 기반으로

실행 중에 있는 프로그램을 가리켜 '프로세스' 라 한다.

따라서 프로세스를 간단히 실행중인 프로그램 으로

설명하기도 한다. 하지만 지금까지 우리가 보아왔던

프로세스들은 프로그램의 흐름을 하나만 형성하고 있다.

main 메소드의 호출을 통해서 하나의 흐름이 형성되며

main메소드의 실행이 완료되면 흐름도 종료가 됬다.


그러나 하나의 프로세스 내에서 둘 이상의 프로그램 흐름을

형성할 수도 있다. 쓰레드 라는 것이 프로세스 내에서

프로그램의 흐름을 형성하는 주체인데 하나의 프로세스

내에 둘 이상의 쓰레드가 존재할 수 있기 때문이다.

다음 아래의 예제로 쓰레드를 만들어보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class ShowThread extends Thread
{
    String threadName;
    public ShowThread(String name) {
        threadName = name;
    }
    
    public void run()
    {
        for(int i = 0; i<100; i++)
        {
            System.out.println("안녕하세요 , " + threadName + " 입니다");
            try{
                sleep(100);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}
 
public class thread {
 
    public static void main(String[] args) {
        ShowThread st1 = new ShowThread("쓰레드1");
        ShowThread st2 = new ShowThread("쓰레드2");
        st1.start();
        st2.start();
        
    }
 
}
cs


1line 에서 정의되어 있는 ShowThread 클래스는

Thread 라는 클래스를 상속하고 있다.

자바에서는 쓰레드도 인스턴스로 표현한다. 때문에 

쓰레드의 표현을 위한 클래스가 정의되어야 하며, 이를

위해서는 Thread라는 이름의 클래스를 상속해야 한다.


쓰레드는 별도의 프로그램 흐름을 구성한다.

즉 쓰레드는 쓰레드만의 main메소드를 지닌다.

단 이름이 main은 아니다. 8line에서 보면 쓰레드의

main메소드의 이름은 run이다. 참고로 8line의 run메소드는

Thread클래스의 run메소드를 오버라이딩 한 것이다.


14line에서의 sleep은 Thread클래스의 static메소드로서

실행 흐름을 일시적으로 멈추는 역할을 한다.

이 문장에서 인자로 100을 전달했으니 이 메소드가

호출되면 이부분에서 1/1000*100초간 흐름을 멈추게 된다.


27,28line에서 Thread클래스를 상속하는 ShowThread의 인스턴스를

두 개 생성 하고 있다. 이렇게 두 개의 쓰레드가 생성된 것이다.


29,30line에서는  위에서 생성한 쓰레드 인스턴스를 별도의

프로그램 흐름을 형성하도록(run메소드 호출)해야한다.

별도의 흐름을 형성하는 방법은 Thread클래스의 정의되어 있는

start메소드를 호출하는 것이다.



위소스를 실행 시켜보면 27,28line 에서 생성한

인스턴스의 run메소드가 동시에 실행되고 있음을 알 수 있다.

main메소드의 실행 이외에 두 개의 실행 흐름을 더 형성한것이다.

이것이 바로 쓰레드를 생성하는 목적이다.


쓰레드의 생성을 보면 의문점들이 생긴다.

그중 대표적으로 중요한 몇가지 의문점들을 보자면


1.쓰레드 인스턴스를 생성후, start메소드를 호출하면

run메소드가 실행되는데 run메소드를 직접 호출하면 안되는지


또한 2.CPU가 하나인데 어떻게 둘 이상의 쓰레드가 동시에

실행이 가능한지와


3.main메소드가 종료되어도 쓰레드는 실행을 계속 하고

쓰레드는 run메소드의 실행이 완료되면 종료하는 지이다.



먼저 첫 번째 답은

run메소드를 직접 호출하는 것이 불가능한 것은 아니다.

하지만 이러한 경우에는 단순한 메소드의 호출일 뿐이지

쓰레드의 생성으로 이어지지 않는다.

쓰레드는 자신만의 메모리 공간을 할당 받아서 별도의

실행흐름을 형성한다. 따라서 자바 가상머신은

start메소드의 호출을 요구하는 것이다.

이것은 우리가 main메소드를 직접 호출하지 않는 것과 비슷한 것이다.


두 번째 답은

모든 쓰레드는 CPU를 공유하기 때문이다.

또한 코어가 여러 개 존재하는 CPU에서는 쓰레드를

각각에 코어가 하나씩 할당되어 실행되기도 한다.


세 번째 답은

쓰레드의 main 메소드가 run메소드이다.

따라서 run메소드의 실행이 완료되면 해당 쓰레드는

종료가 되고 소멸된다. 그리고

위에서 실행 했던 소스에서는 main메소드 내에서

쓰레드를 생성 했었다. 그런데 쓰레드를 생성하고

start메소드를 호출한다고 해서 main메소드가 멈춰서는 것은 아니다.

main메소드도 다른 쓰레드와 마찬가지로 자신만의 실행 흐름을 이어간다.

따라서 main메소드가 먼저 종료 될수도 있다. 하지만

main 메소드가 종료되어도 실행 중에 있는 쓰레드가 있다면

프로그램은 종료되지 않는다 그리고 main메소드도 쓰레드에 의해 실행된다.

결국 마지막 남은 쓰레드까지 실행을 완료해야 프로그램은 종료 된다.





댓글

Designed by JB FACTORY