불규칙적으로 변하는 것은 아닙니다. 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()을 모두 마치고 종료했을 것이기 때문입니다.
'자바 Threads Programming > Basic' 카테고리의 다른 글
Thread-7.경쟁하는 Thread와 공유당하는 객체 (0) | 2008.01.09 |
---|---|
Thread-6.Thread 우선순위 (0) | 2008.01.07 |
Thread-4.간단한 Thread 검색 프로그램 (0) | 2007.12.28 |
Thread-3.Thread와 Thread의 상속 (0) | 2007.12.28 |
Thread-2.Thread의 사용방법 (0) | 2007.12.18 |