+. Wait set - 쓰레드 대합실
wait set 은 인스턴스의 wait 메소드를 실행한 후 동작을 정지하고 있는 쓰레드들의 집합이다.
쓰레드는 wait 메소드를 실행하면 동작을 일시 정지하고 wait 셋이라고 하는 대합실로 들어간다.
- 다른 쓰레드에서 notify 메소드에 의해 깨어난다.
- 다른 쓰레드에서 notifyAll 메소드에 의해 깨어난다.
- 다른 쓰레드에서 interrupt 메소드에 의해 깨어난다.
- wait 메소드가 타임아웃 된다.
wait 메소드를 실행하기 위해서는 쓰레드가 락을 가지고 있어야 한다.
락을 취한 쓰레드 A 가 wait 메소드를 실행한다.
쓰레드 A는 wait 셋에 들어가 락을 해제한다.
쓰레드 B는 락을 설정할 수 있게 된다.
notify 메소드를 사용하면 wait 셋에 있는 쓰레드 한 개를 wait 셋에서 꺼낸다.
락을 취한 쓰레드 B가 메소드를 실행한다.
쓰레드 A가 wait 셋에서 나와 wait 다음 순서로 남어가려 하지만 notify 를 실행한 쓰레드 B가
notify를 실행한 쓰레드 B가 락을 해제한다.
notify 메소드를 실행했을 때 wait 셋에서 대기 중인 쓰레드가 여러개라고 하자. 이 때 어느 쓰레드가 선택될지는 정해져 있지 않다. 제일 먼저 wait 한 쓰레드가 선택될지 무작위로 선택될지 그 밖의 방법으로 선택될지는 Java 처리계에 따른다. 그러므로 선택된 쓰레드에 의존하여 프로그램을 작성하는 것은 바람직하지 않다.
|
notifyAll 메소드를 사용하면 wait 셋에 있는 모든 쓰레드를 wait 셋에서 꺼낸다.
notifyAll 을 호출하여 wait 셋에 있는 쓰레드들을 깨운다.
notiffyAll을 호출한 쓰레드가 락의 소유권을 해제한다.
블락되어 있는 쓰레드들 중 락을 소유한 쓰레드만이 수행을 재개한다.
다시 다음과 같이 wait 셋이 구성 될 것이다.
notify 메소드와 notifyAll 메소드는 많이 비슷하다. 그렇다면 어느 쪽을 써야 할까?
|
wait, notify, notifyAll 의 동작을 떠올려 보자.
- obj.wait 은 obj의 wait 셋에 현재의 쓰레드를 넣는다.
- obj.notify 는 obj의 wait 셋에서 1개의 쓰레드를 깨운다.
- obj.notifyAll 은 obj 의 wait 셋에 있는 모든 쓰레드를 깨운다.
참고 : Java 언어로 배우는 디자인 입문 : 멀티쓰레드편
Thread의 상태
Java 5의 Thread.getState() 메소드는 Thread의 현재 상태를
Thread.State Enum으로 리턴한다. Thread.State Enum의 정의는 아래와 같다.
BLOCKED Thread state for a thread blocked waiting for a monitor lock. |
NEW Thread state for a thread which has not yet started. |
RUNNABLE Thread state for a runnable thread. |
TERMINATED Thread state for a terminated thread. |
TIMED_WAITING Thread state for a waiting thread with a specified waiting time. |
WAITING Thread state for a waiting thread. |
BLOCKED 상태는 Sychronized에 의해 점유된 Monitor를 획득하지 못하고
기다리는 상태임을 의미한다.
반면 WAITING이나 TIMED_WAITING 상태는 wait 메소드를 이용해 자신이
획득한 Monitor를 반환하고 Waiting Pool에 대기하고 있음을 의미한다.
RUNNABLE 상태는 현재 실제로 작업을 할 수 있는 상태이거나
작업을 수행 중인 상태를 의미한다.
이 상태들에 대한 정확한 이해가 Thread들간의 Lock 경합을 이해하는데
필수적이다.
만일 특정 Thread가 특정 Object의 Monitor를 장시간점유하고 있다면,
동일한 Monitor를 필요로 하는 다른 모든 Thread들은 BLOCKED 상태에서
대기하게 된다.
이 현상이 지나치게 되면 Thread 폭주가 발생하고 자칫 System 장애를
유발하게 된다. 이런 현상은 wait 메소드를 이용해 대기를 하는 경우도
마찬가지이다.
특정 Thread가 장시간 notify를 통해 Wait 상태의 Thread들을 깨워주지 않으면
수많은 Thread 들이 WAITING이나 TIMED_WAITING 상태에서 대기하는 현상이
발생하게 된다.
'IT_Programming > Java' 카테고리의 다른 글
Java Real-time Heap Dump 생성 (0) | 2011.06.22 |
---|---|
[펌] IBM JVM 에서 Memory Leak의 발견과 대처 (0) | 2011.06.22 |
Java Security Manager & Java policy 파일 생성 (0) | 2011.06.10 |
GC Dump 보기 (0) | 2011.05.19 |
Java Closure Example (0) | 2011.05.12 |