gpt4 book ai didi

java - 为什么 'notify' 会唤醒所有等待线程,尽管只有一个线程受到影响?

转载 作者:行者123 更新时间:2023-12-02 12:57:49 26 4
gpt4 key购买 nike

在下面的代码中,两个消费者线程启动并进入等待状态。之后生产者线程启动(很可能)并调用“notify”。所有线程都使用生产者作为监视器。

Thread producer = new Thread() { 
@Override
public void run() {
synchronized (this) {
System.out.printf("notify at %d %n", getId());
notify();
}
}
};

Runnable consumer = () -> {
try {
synchronized (producer) {
long id = Thread.currentThread().getId();
System.out.printf("wait at %d %n", id);
producer.wait();
System.out.printf("awakened: %d %n", id);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};

Stream.generate( () -> consumer )
.limit(2)
.map(Thread::new)
.forEach(Thread::start);

Thread.sleep(3000); // consumer threads are (likely) waiting

producer.start();

来自 Object.notify 的 javadoc :

Wakes up a single thread that is waiting on this object's monitor.

代码产生以下(或类似)输出:

  wait at 13 
wait at 14
notify at 12
awakened: 13
awakened: 14

重点是两个消费者线程都被唤醒,而不仅仅是其中一个。为什么?

在 Windows 10 64 位下使用 OpenJDK 运行时环境 AdoptOpenJDK(内部版本 11.0.5+10)进行编译和测试。

提前致谢!

最佳答案

问题在于,您使用Thread作为监视器,而不是任意对象

Thread 在内部使用信号,如 Thread.join 中所述:

As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

一般建议是始终使用专用对象来等待/通知,其他代码无法访问,以避免像这样的“虚假”通知或等待。

关于java - 为什么 'notify' 会唤醒所有等待线程,尽管只有一个线程受到影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60637994/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com