2010-11-28 2 views
2

스레드 1 :간단한 자바 동시성 문제

if(!conditionFullfiled) this.wait(); 

스레드 2 :

if(conditionFullfiled) thread1.notify(); 

내가 스레드 2에서 스레드 하나를 깨워 할 몇 가지 조건이 fullfiled 때. 그러나 문제가되지 않습니다. thread1.notify()if(!conditionFullfiled) ***HERE*** this.wait();이라고 할 때?

답변

3

obj.wait()obj.notify()을 수행하려면 기다리거나 알릴 대상의 모니터를 소유해야합니다. 귀하의 코드에서, 당신은 아마 thread1.notify() 싶지 않아요. 예 :

Object someSharedObject = ... 

Thread1 :

synchronized(someSharedObject) { 
    // while NOT if for spurious wake ups. 
    while(!conditionFullfiled) someSharedObject.wait(); 
    } 

Thread2 :

synchronized(someSharedObject) { 
    if(conditionFullfiled) someSharedObject.notify(); // this wakes thread1 
    } 

synchronized 잠금이 두 스레드가 충돌하지 않습니다 의미 (this 될 수 있습니다) someSharedObject에 있습니다. .wait()은 현재 보류 된 모니터를 해제하므로 Thread1이 대기 중이면 Thread2가 차단되지 않습니다.

편집 : 가짜 깨우기에 대해 알게되었습니다. .wait()while 루프 - if으로 충분하지 않아야합니다. Why do threads spontaneously awake from wait()?. Enio Shioji에게 저를 가르쳐 주셔서 감사합니다.

편집 : 명확한 .wait() 모니터가 출시되었습니다.

+0

는'if'가 while''으로 대체되어야 읽기 가짜 깨우기에 대처하십시오. –

+0

'someSharedObject.wait();'가 synchronized 블록 내에서 호출됩니다. Thread1이 이미 대기중인 경우 Thread2가 다른 동기화 된 블록으로 절대 들어 가지 않는다는 것을 의미하지 않습니까? – fhucho

+0

@fhucho, wait()는 현재 보유하고있는 모니터를 해제합니다. –

0

"this"로 사용하는 개체는 무엇입니까? 당신이 thread1 객체() 대기를 호출하고, 당신이 보여 두 문이 같은 루프에 싸여있는 경우 : 당신이 원하는대로

new Runnable() { 
    synchronized (thread1) { 
     thread1.wait() 
    } 
} 

는 그런 다음 코드는 작동합니다. (조건이 거짓 일 때 첫 번째 쓰레드는 멈추고 다르게 작동합니다). 트릭은 스레드 객체의 상호 작용이 동기화되므로 다른 객체가 객체와 함께 작업하는 동안 한 스레드가 인터럽트 할 수 없다는 것입니다.

편집 : 스레드가 아닌 다른 개체 (단순히 잠금을 제공하는 순수 개체를 만들 수 있음)에서 동기화하는 것이 더 좋습니다.

0

기다림 해제 객체 잠금 (이 경우) 이후 전혀 문제가 없습니다.

가짜 깨우기를 피하려면 while 블록에서 대기/알림 조건을 보호하는 것이 가장 좋습니다.

3

여기에는 2 가지 문제가 있습니다.

  1. 스레드 개체 자체에서 wait() 및 notify()를 호출하면 안됩니다. 이를 수행하는 더 좋은 방법은 특별한 잠금 객체를 사용하는 것입니다.

    private Object lock = new Object(); ...... lock.wait();

  2. 다음 문제는 모두 대기 (전화) 및 synchornized 블록에 통지해야한다는 것입니다 즉

    원 공급기 (잠금) { // 일부 코드 lock.wait(); 하나 개의 클래스에 모두 wait()notify() 포장 방법을 지역화하는 것이 편리하다

    syncronized(lock) { 
        lock.notify(); // this line will cause the wait to terminate and the first thread to continue. 
    } 
    

    , 그래서 그들은 개체를 잠글 액세스 할 수 있습니다

}

다음 코드에서 다른 장소에서 말한다. 자세한 내용은

http://download.oracle.com/javase/6/docs/api/ http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html