Java Thread notify( ) vs. notifyAll()



我对Java的notify()有点困惑。以下示例来自教科书。

public synchronized consume() {
    while(queue.isEmpty()) {
        try{ wait(); } catch (InterruptedException e) {}
    }
    // Assume that getElement() notifies to producers.
    element = queue.getElement();
    ...
}
public synchronized produce() {
    while(queue.isFull()) {
        try{ wait(); } catch (InterruptedException e) {}
    }
    element = new Element();
    ...
    queue.addElement(element);
    notifyAll();
}

我非常了解上面示例中produce()的方法。但是,谁能告诉我为什么我们不在第一种方法(consume())结束时使用notifyAll()?简而言之,为什么不像这样:

public synchronized consume() {
    while(queue.isEmpty()) {
        try{ wait(); } catch (InterruptedException e) {}
    }
    // Assume that getElement() notifies to producers.
    element = queue.getElement();
    ...
    notifyAll();
}

多谢!

此致敬意。

我@Slash同意你的看法。 在您的代码示例中,由于您要从队列中删除 and 元素,因此需要有人通知在isEmpty()循环中等待的生产者。 但是,您的代码说:

// Assume that getElement() notifies to producers.
element = queue.getElement();

所以该评论意味着不知何故getElement()打电话notify()notifyAll().

简而言之,为什么不像这样:

是的,尽管您需要删除注释,但您的代码仍然可以工作。 :-)

通常在这些生产者/使用者模式中,有两个锁:一个在队列为空时,另一个在队列已满时。 然后,当队列不再已满时,使用者可以向生产者发出信号,而不会唤醒其他使用者。 在这种情况下,您也可以使用单个notify()因为您只需要唤醒单个使用者或单个生产者。 此处使用notifyAll()是因为只有一个对象synchronized

此外,对于后代来说,注意while()循环不是if语句非常重要。 即使使用notify()和两个锁,也必须保护多生产者/使用者模型中的争用条件。 虚假唤醒也是一个问题。 更多关于这里:

http://256stuff.com/gray/docs/misc/producer_consumer_race_conditions/

在这种情况下,在生产时使用通知,告诉消费者现在有东西要消费,以便其中一个可以唤醒并消费它。

当消费者刚刚消费了某些东西时通知假设发生在getElement()中:

// Assume that getElement() notifies to producers.

相关内容

  • 没有找到相关文章

最新更新