有一个主线程有一个while循环,在这个while循环中,他检查一些条件,如果所有条件都满足,他启动另一个线程进入wait()状态。
其他并行运行的线程在工作完成时通知主线程。
在主线程进入等待状态之前, “子线程”通知主线程存在问题=死锁。
避免它的最佳做法是什么?
有一个主线程有一个while循环,在这个while循环中,他检查一些条件,如果所有条件都满足,他启动另一个线程进入wait()状态。
其他并行运行的线程在工作完成时通知主线程。
在主线程进入等待状态之前, “子线程”通知主线程存在问题=死锁。
避免它的最佳做法是什么?
只要确保主线程不等待已经发生的事情。(为什么会有人这样做?这没有任何意义。)
简单的答案是使用 Java 5 中的并发包。 CountDownLatch 似乎适合这里。
如果您仅限于 Java 5 之前的环境,则必须创建一个使用相同算法的自定义实现。创建所有子线程后,主线程将调用 signalReady。子线程将在完成工作后调用 signalComplete。
一个简单的实现是有一个名为 Latch 的对象,它有两个两个成员字段。
下面的实现将适用于一个父母和一个孩子。对于其他孩子,可以为每个孩子提供自己的锁存器,以在完成时发出信号。在某些情况下,这将是竞争条件。在信号之间添加自旋锁或睡眠会降低竞争条件的可能性。它不会消除它
class Latch{
Object readyLock;
Object completeLock;
public void signalComplete(){
synchronized(readyLock){
readyLock.wait()
}
//spin lock as a precaution
synchronized(completeLock){
completeLock.notify()
}
}
public void signalReady(){
synchronized(readyLock){
readyLock.notify()
}
synchronized(completeLock){
completeLock.wait()
}
}
}
希望这可以帮助!
我更喜欢使用 Explicit Locks。请参阅 Java 并发 API。
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html
使用信号量进行通知。
就是这样,真的。信号量有一个计数并且可以记录通知,直到主线程开始等待它。
一种非常常见的做法是,几乎总是将wait()
方法置于while
循环中,其“迭代条件”是检查是否发生了特定事件,一旦发生,其他线程就会调用该notify()
方法。
前任:
while(!event_occurrence) {
...
wait();
...
}
event_occurrence
另一个线程将调用notify()
方法的事件在哪里。