Thread는 만들어져서 종료할 때까지 상태가 계속 변하게 됩니다.  그렇다고 카멜레온 처럼

불규칙적으로 변하는 것은 아닙니다. Thread Create상태, Runnable상태, Not Runnable

상태,Dead 상태등 4가지 중 하나를 가지게 됩니다. 적어도 여러분이 만든 Thread

4가지 중 하나입니다.

 

 

 

/**

* Thread Life Cycle을 보여줍니다.

*/

public class LifeCycle {

    public static void main(String[] args) {

        Runnable task = new Task();                                        // Runnable객체를 만듭니다.

 

        Thread thread = new Thread(task);     // Thread를 만듭니다.

       

        if (thread.isAlive())                                                     

            System.out.println("thread is alive");

        else

            System.out.println("thread isn't alive");

 

        thread.start();                                  

 

        if (thread.isAlive())              

            System.out.println("thread is alive");

        else

            System.out.println("thread isn't alive");

 

        try {

            Thread.sleep(1000*5);    // Main Thread 5(5000 ms)간 재웁니다.

        }

        catch(InterruptedException ie) { }      

 

        if (thread.isAlive())

            System.out.println("thread is alive");

        else

            System.out.println("thread isn't alive");

    }

}

 

/**

* "Doing Task"를 출력한후 약3초간 잡니다. 그리고 종료합니다.

*/

class Task implements Runnable {

 

    public Task() {;

    }

    public void run() {

        System.out.println("Doing Task");       

        try {

            Thread.sleep(1000*3);                

        }

        catch(InterruptedException ie) { }

    }

}

예제 8 - 1 LifeCycle.java

 

 

예제 8 - 1 Thread Life Cycle을 간명하게 설명하고 있습니다.

예제 8 - 1 LifeCycle.java 에는 두개의 클래스가 있습니다. 그중 Task 클래스는 Runnable

입니다.  Task Runnable 클래스는 간단한 메시지를 화면에 출력하고 약 3초간 자다가 끝을

내는 단순한 일을  정의한 객체입니다. 그러니까 Task Runnable 객체를 실행하는 Thread

경우는 약 3초 후에는 Runnable 객체의 public void run() 메소드를 모두 마치게 되겠지요.

 


사용자 삽입 이미지

그림 8 - 1

 

LifeCycle 클래스의 public static void main(String[] )을 살펴보면 Task Runnable객체를

만들고 Task Runnable객체를 이용해서 Thread 객체를 하나 만들었습니다.

Create 상태

 

Thread thread = new Thread(task);

Create상태의 Thread

처럼 말입니다.

이때는 Thread객체가 막 만들어진 상태입니다. 이때 Thread 상태가  Create상태 입니다.

Create상태의 Thread는 일반 객체와 마찬가지로 메모리에 객체가 하나 있는 것 일뿐

Thread로서 어떠한 일도 할 수 없는 무능력의 상태입니다.  CPU등의 시스템 자원을

적극적으로 사용해서 File을 읽고,네트워크 연결을 하고하는 일을 할 수 없지요.

예제 8 - 1 LifeCycle에서 Thread에 대한 레퍼런스 thread를 이용해서 public boolean

isAlive() 메소드를 여러 번 호출하는데, Thread가 만들어진 직후에도 isAlive() 메소드를

호출해서 Thread의 상태를 확인해 보고 있습니다.

public boolean isAlive()는 메소드 이름에서 느끼겠지만 Thread가 살아 있는지 여부를

알아내는데 사용됩니다. 예상하시겠지만 이때의 boolean 값은 false 입니다.

이는 갓 만들어진 Thread CPU등의 시스템자원을 할당받아 독립적인 일을 수행할 수

있는 온전한 Thread로서의 의미를 아직 가지지 못했다는 뜻입니다.

 

Runnable 상태

Create상태의 Thread가 온전한 Thread로서 의미를 가지려고 한다면

thread.start();

Runnable상태의 Thread

처럼 start()메소드가 호출 되어야 합니다.

 

갓 만들어진 Thread start()메소드가 호출되어야만 thread thread로서 의미를 가지게

됩니다. 이때의 상태가 그 유명한 Runnable상태 입니다.

예제 8 - 1 LifeCycle에서는 Runnable상태의 Thread에게 isAlive()메소드를 호출하고

있는데, 예상하시겠지만 이때의 값은 true입니다.

 

하지만 Thread의 상태가 Runnable상태인것과 실제로 Thread가 일을 수행하고 있는 것과는

다른 얘기입니다. Thread Runnable상태 이더라도 Thread가 일을 하지 않고 놀고 있을 수

있습니다. 왜 일까요? 이유는 간단합니다. 시스템 자원이 한정되어 있기 때문입니다.

 

모든 컴퓨팅 시스템에는 자원이 한정되어 있습니다.

대표적인 시스템 자원인 CPU의 예를 들면 보통 몇 개 정도, 많아봐야 수십개 정도일텐데,

시스템에서 한꺼번에 생성되서 동시에 일을 수행하는 Thread의 개수는 여기에 비하면

엄청나게 많습니다. 모든 Thread는 일을 하기 위해서는 CPU가 필요한데, CPU를 확보

하지 못하면 그 CPU는 일을 못하고 놀고 있다는 얘기입니다.

Thread Runnable 상태이지만 실제로는 일을 못하고 놀고 있습니다.

대부분 start()메소드가 호출된 많은 Thread가 이런 상태(Runnable상태이면서,당장 일을

하고 있지는 않은 상태)일 것입니다.

Runnable상태의 Thread CPU등의 자원을 할당 받아야만 실제로 일을 할 수 있습니다.

자바는 CPU등의 시스템 자원을 기다리는 Runnable Thread에게 시스템 자원을 적절히

분배해 주는데 이를 스케쥴링이라고 합니다.

, Runnable Thread는 기회가 주어지면 열심히 일을 할 수 있는 Thread의 상태를

말합니다. 물론 매우 빨리 기회가 옵니다.

예제 8 - 1에서 Thread Runnable상태가 된후에는 Main Thread Task Thread

경쟁하면서 일을 수행합니다.

스케쥴러는 Main Thread Task Thread에게 시스템자원을 분배해주게 되지요.

우선 Task Thread Task Runnable public void run()을 수행하는데, Task Runnable

Thread로 하여금 실행하도록 한 일은 간단한 문자열을 출력 하고, 3초정도 잠잔다음

끝을 내는 겁니다. Task Thread Task Runnable public void run()을 수행하면서 많은

변화를 겪게 됩니다.

 

Not Runnable 상태

 

Thread Runnable상태에서 일을 수행하다가 sleep(), wait() 드의 메소드를 호출하거나

블록되는 I/O를 수행한 경우는 Not Runnable 상태로 곧바로 후퇴합니다.

예제 8 - 1 Task Thread의 경우는

try {

        Thread.sleep(1000*3);                      

    }

    catch(InterruptedException ie) { }

Thread.sleep(1000*3) 부분을 수행할 때 Not Runnable상태로 후퇴합니다.

 

Thread Not Runnable상태가 되면 CPU등을 전혀 할당받을 수 없어서 일을 진행할 수

없습니다. 스케쥴러가 CPU를 할당하는 Thread를 오직 Runnable Thread들 중에서 고르기

때문입니다. Thread CPU를 할당받기 위해서 반드시 Runnable상태로 돌아와야합니다.

Thread Not Runnable 상태에서 Runnable상태로 돌아오기 위해서는 Thread.sleep()

호출한 경우는 지정한 시간이 모두 흘러갔을 때, Object.wait()를 호출한 경우는

3 Thread Object.notify() 혹은 Object.notifyAll()을 호출해줄 때, 블록된 I/O의 경우

I/O가 끝난 경우 등입니다.

예제 8 - 1 Task thread의 경우는 Thread.sleep(long)을 호출한 후 3초가 지나면

Runnable 상태가 될 수 있는 것입니다.

하지만 Task thread Runnable상태로 복귀했다고 바로 일을 시작할 수 있는 것은

아니고, 많은 Runnable상태의 Thread들과 CPU등 시스템자원을 두고 경쟁을 해야만 합니다.

 

Not Runnable상태의 Thread의 경우 Thread isAlive() 메소드를 호출하게 되면 true

리턴합니다. , Runnable상태, Not Runnable상태의 Thread의 경우는 isAlive()에 대한

답은 true입니다. 바꾸어 말하면 Thread Runnable상태인지, Not Runnable상태인지는

프로그래머는 알수가 없습니다.

예제 8 - 1 2번째 isAlive()메소드 호출은 Task Thread sleep()메소드를 호출한 상태

일 것이므로 Not Runnable 상태이고 그 결과 값은 true입니다.

 

Dead상태

Thread가 가질수 있는 마지막은 Dead상태입니다.

Thread Dead상태가 될때는 Runnable public void run() 메소드를 마친 후입니다.

Dead상태인 Thread isAlive()를 호출하면 false를 리턴합니다.

 

Thread Create상태,Dead상태 모두 false를 리턴하기 때문에 Thread Create상태인지, Dead상태인지 알 수는 없습니다.

그러나 Create상태의 Thread start()시킬수는 있지만 Deat 상태의 Thread start()

시킬수는 없으니 유의해야겠습니다.

 

예제 8 - 1의 세번째 isAlive()메소드 호출을 통해 Main Thread에서 Task Thread

상태를 알아봅니다. 물론 결과는 false를 리턴합니다.

Task Thread Dead상태이기 때문입니다. 이유는 Main Thread는 약 5초간 sleep했고,

Task Thread 3초만 sleep했으므로,Main Thread isAlive()를 호출했을 무렵 Task thread

public void run()을 모두 마치고 종료했을 것이기 때문입니다.

Posted by
,