我有一个线程启动另一个线程执行一个动作,它会导致事件在运行后触发。我需要在第一个线程中捕获该事件(通过事件侦听器)并继续其余的工作。我的问题是,当第一个线程正在等待事件监听器调用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