我曾经写过一个synchronized像以下一样的块:
synchronized(foobar) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
但是,最近我看到有人写道:
synchronized(foobar) {
// do something
foobar.notifyAll();
}
Run Code Online (Sandbox Code Playgroud)
有foobar.notifyAll();必要吗?如果我省略它会怎么样?
简短的答案是,这取决于您在做什么。
如果同步块的目标只是确保安全地执行对数据结构的访问/更新,那么notify()ornotifyAll()就没有任何作用。
另一方面,如果目标是实现“条件变量”,那么notify()ornotifyAll()调用将与这样的调用一起工作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();
}
}
Run Code Online (Sandbox Code Playgroud)
上面实现了一个简单的机制,其中线程调用awaitFlag()等待flag变为true或false。当另一个线程调用setFlag()更改标志时,当前正在等待标志更改的所有线程都将被notifyAll(). notifyAll()这是一个对于代码的工作至关重要的示例。
因此,要了解notify或notifyAll代码是否必要,您需要弄清楚其他代码是否可能调用wait同一互斥体/锁定对象。