在同步块结束时是否需要notifyAll()?

Wen*_* Ji 5 java

我曾经写过一个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();必要吗?如果我省略它会怎么样?

Ste*_*n C 5

简短的答案是,这取决于您在做什么。

如果同步块的目标只是确保安全地执行对数据结构的访问/更新,那么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变为truefalse。当另一个线程调用setFlag()更改标志时,当前正在等待标志更改的所有线程都将被notifyAll(). notifyAll()这是一个对于代码的工作至关重要的示例。


因此,要了解notifynotifyAll代码是否必要,您需要弄清楚其他代码是否可能调用wait同一互斥体/锁定对象。


poi*_*oae 4

你不需要这样做foobar仅当对象(此处)正在等待通知时才需要执行此操作。仅通知唤醒在此对象监视器上等待的所有线程。