我曾经写过一个synchronized
块,如:
synchronized(foobar) {
// do something
}
但是,最近我看到有人写道:
synchronized(foobar) {
// do something
foobar.notifyAll();
}
foobar.notifyAll();
是否必要?如果我省略它会怎么样?
答案 0 :(得分:4)
您不需要来执行此操作。如果对象(此处为foobar
)正在等待通知您,则只需执行此操作。仅通知Wakes up all threads that are waiting on this object's monitor.
答案 1 :(得分:3)
简短的回答是取决于你在做什么。
如果synchronized块的目标只是确保安全地执行对数据结构的访问/更新,则notify()
或notifyAll()
没有用处。
另一方面,如果目标是实现“条件变量”,则notify()
或notifyAll()
调用可以使用wait
这样的调用...例如:
private boolean flag;
private final Object mutex = new Object();
public void awaitFlag(boolean flag) {
synchronized (mutex) {
while (this.flag != flag) {
mutex.wait();
}
}
}
public void setFlag(boolean flag) {
synchronized (mutex) {
this.flag = flag;
mutex.notifyAll();
}
}
以上实现了一种简单的机制,其中线程调用awaitFlag()
以等待flag
成为true
或false
。当另一个线程调用setFlag()
来更改标志时,当前等待标志更改的所有线程将被notifyAll()
唤醒。这是notifyAll()
对代码工作至关重要的示例。
因此要了解notify
或notifyAll
代码是否必要,您需要确定某些其他代码是否在同一个互斥锁上调用wait
/ lock object。
答案 2 :(得分:2)
在Java中,您可以使用wait()
,notify()
和notifyAll()
来实现线程协调。见How to use wait and notify in Java?
答案 3 :(得分:1)
notifyAll()告诉睡在foobar.wait()中的任何其他线程,当前线程即将释放锁,他们可以再次竞争资源。