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

时间:2013-02-12 15:56:22

标签: java

我曾经写过一个synchronized块,如:

synchronized(foobar) {
    // do something
}

但是,最近我看到有人写道:

synchronized(foobar) {
    // do something
    foobar.notifyAll();
}

foobar.notifyAll();是否必要?如果我省略它会怎么样?

4 个答案:

答案 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成为truefalse。当另一个线程调用setFlag()来更改标志时,当前等待标志更改的所有线程将被notifyAll()唤醒。这是notifyAll()对代码工作至关重要的示例。


因此要了解notifynotifyAll代码是否必要,您需要确定某些其他代码是否在同一个互斥锁上调用wait / lock object。

答案 2 :(得分:2)

在Java中,您可以使用wait()notify()notifyAll()来实现线程协调。见How to use wait and notify in Java?

答案 3 :(得分:1)

notifyAll()告诉睡在foobar.wait()中的任何其他线程,当前线程即将释放锁,他们可以再次竞争资源。