我有一個線程啓動另一個線程執行一個動作,它會導致事件在運行後觸發。我需要在第一個線程中捕獲該事件(通過事件偵聽器)並繼續其餘的工作。我的問題是,當第一個線程正在等待事件監聽器調用notify()
時,它是否會釋放監視器?如果不是,我該如何設計這個算法?我是否正確使用wait()
和notify()
方法以及正確的鎖定(thread1)?在同步塊中使用wait()方法時,JVM會在等待notify()時釋放監視器嗎?
這是怎樣的代碼看起來像:
public class Thread1 {
public void run() {
Thread thread1 = Thread.currentThread();
EventListener listener = new EventListener(thread1);
Performer performer = new Performer();
performer.addOnPerformedListener(listener);
synchronized(thread1) {
performer.run(); // Launches thread 2
thread1.wait();
}
...
}
public class EventListener implements Performer.OnPerformedListener {
private Thread thread;
public EventListener(Thread thread) {
this.thread = thread;
}
@Override
public void onPerformed() {
synchronized (thread) {
thread.notify();
}
}
}
}
下面是一個javadoc參考,也可以幫助:http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait() – ash 2014-08-31 04:06:48
感謝您的答案。我首先包含了一個條件標誌,但是之後根據在執行操作之前條件檢查也會發生並且該標誌設置爲true的原因將其刪除。但是,我發現它有一些安全價值。 – exbuddha 2014-08-31 16:45:22
我不會認爲它是「安全」。相反,請考慮所有可能的操作順序。我使用的方法是遍歷代碼,一次一個部分,並考慮如果代碼停在那裏會發生什麼,而其他競爭線程同時執行競爭代碼。例如,啓動另一個線程然後等待通知,如果另一個線程在第一次進入等待呼叫之前通知會發生什麼情況?錯過了通知。對第二個線程的整個操作的鎖定太粗糙,甚至引發了另一個線程的問題。 hth – ash 2014-08-31 17:54:37