CODEDRAGON ㆍDevelopment/Java
Object 클래스의 wait(), notify(), notifyAll()
· 동기화된 스레드는 동기화 블록에서 다른 스레드에게 제어권을 넘기지 못합니다. 즉, 한 쓰레드가 lock(제어권)을 획득한 채로 오랜 시간을 보내게 되면 다른 쓰레드들은 모두 해당 객체의 lock을 기다리느라 다른 작업들도 원활히 진행되지 못하게 됩니다.
· 이와 같은 문제를 해결하기위해 동기화된 블록에서 스레드간의 통신(제어권을 넘기기)하기 위해서는 wait(),notify(),notifyAll() 메서드를 사용해야 합니다.
· 이 메서드를 사용할 때 주의 해야할 점은 synchronzied 블록에서만 의미가 있습니다. Synchronized 블록이 아닌 곳에 사용할 경우 java.lang.IllegalMonitorStateException이 발생합니다.
· 두 개의 스레드를 교대로 실행해야하는 정확한 교대작업이 필요한 경우 자신의 작업이 끝나면 상대방 스레드를 일시 정지 상태에서 풀어주고, 자신은 일시정지상태로 만들어주면 됩니다. 이 방법에 공유 객체가 사용되며 공유객체는 두 스레드가 작업할 내용을 각각 동기화 메소드로 구분해 놓습니다. 한 스레드가 작업을 완료하면 notify()메소드를 호출해서 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만들고, 자신은 두 번 작업을 하지 않도록 wait()메소드를 호출하여 일시 정지 상태로 만듭니다.
wait(), notify(), notifyAll()
wait(), notify(), notifyAll()는 특정 객체에 대한 것이여서 Object클래스에 정의되어 있습니다. Object클래스에서 선언된 메소드이므로 모든 공유 객체에서 호출 가능합니다.
wait()가 호출되면 실행 중이던 쓰레드는 해당 객체의 Waiting pool로 이동한 다음 통지를 기다립니다. notify()가 호출되면 해당 객체의 Waiting pool에 있던 모든 쓰레드 중에서 임의의 쓰레드만 통지를 받습니다. notifyAll()은 기다리고 있는 모든 쓰레드에게 통보를 하지만 lock을 얻을 수 있는 것은 하나의 쓰레드 뿐이고 나머지 쓰레드는 통보를 받긴하지만 lock을 얻지 못하면 다시 lock을 기다리게 됩니다.
코드 |
설명 |
public final void wait() throws InterruptedException |
· wait 함수를 호출한 쓰레드는 notify 또는 notifyAll 메소드가 호출될 때까지 블로킹된 상태에 놓이게 됩니다. · lock을 반납하고 기다리게 됩니다. 그러면 다른 쓰레드가 lock을 얻어 해당 객체에 대한 작업을 수행하게 됩니다. |
public void wait(long timeout) public void wait(long timeout, int nanos) |
· 지정된 timeout 시간이 지난 후에 자동적으로 notify()가 호출된는 것과 같습니다. |
public final void notify() |
· wait 함수의 호출을 통해서 블로킹된 상태에 놓여있는 쓰레드 하나를 깨워 실행 대기 상태로 만듭니다. · wait 함수로 작업을 중단했던 쓰레드가 다시 lock을 얻어 작업을 진행하게 됩니다. |
public final void notifyAll() |
· wait 함수의 호출을 통해서 블로킹 상태에 놓여있는 모든 쓰레드를 깨워 실행 대기상태로 만듭니다. |
Class Object
https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
synchronized블록을 통해 하나의 쓰레드만 호출할 수 있도록 동기화 처리
wait(), notify(), notifyAll()는 동기화 블록내에서만 사용할 수 있습니다.
Synchronized 블록이 아닌 곳에서 호출할 경우 java.lang.IllegalMonitorStateException이 발생합니다.
synchronized(this){
wait( );
notify( );
notifyAll( );
}
|
java.lang.IllegalMonitorStateException
Synchronized 블록이 아닌 곳에서 wait(),notify(),notifyAll() 메서드 호출시 Exception 발생합니다.
Object의 wait(),notify(), notifyAll()의 흐름도
wait()를 통해 lock을 반납한 후 다시 lock을 얻어서 임계영역에 들어가는 것을 재진입(reentrance)라고 합니다.
'Development > Java' 카테고리의 다른 글
일반적인 입출력의 대상, 자바 I/O기준, I/O 모델 (0) | 2017.10.24 |
---|---|
스트림의 특징 (0) | 2017.10.24 |
스레드 상태제어, 스레드 상태제어 메소드, 스레드 상태제어 메소드 도식도 (0) | 2017.10.24 |
Thread life cycle(스레드의 생명주기) (0) | 2017.10.24 |
인터페이스간의 상속 (0) | 2017.10.23 |