java - wait() 和 notifyAll() 的奇怪行为
问题描述
我发现自己对 wait() 和 notifyAll() 的这种行为感到困惑:
import java.util.LinkedList;
import java.util.Queue;
class Producer implements Runnable {
Queue<Integer> sharedMessages;
Integer i = 0;
Producer(Queue<Integer> sharedMessages) {
this.sharedMessages = sharedMessages;
}
public void produce(Integer i) {
synchronized (sharedMessages){
System.out.println("Producing message " + i);
this.sharedMessages.add(i);
}
}
public void run(){
synchronized (sharedMessages) {
while (i < 100) {
produce(i++);
}
}
}
}
消费者:
class Consumer implements Runnable{
Queue<Integer> sharedMessages;
Consumer(Queue<Integer> sharedMessages) {
this.sharedMessages = sharedMessages;
}
public void consume() {
synchronized (sharedMessages) {
System.out.println(sharedMessages.remove() + " consumed by " + Thread.currentThread().getName().toString());
}
}
@Override
public void run(){
synchronized (sharedMessages){
while(sharedMessaged.size() > 0){
System.out.println(Thread.currentThread().getName() + " going to consume");
consume();
try {
sharedMessages.wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + ": I was interrupted from my sleep!");
}
sharedMessages.notifyAll();
}
}
}
}
这是我创建线程的方式:
public class Main {
public static void main(String[] args) {
Queue<Integer> sharedMessages = new LinkedList<>();
new Thread(new Producer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
new Thread(new Consumer(sharedMessages)).start();
}
}
输出看起来像这样:
Producing message 0
Producing message 1
...
Producing message 98
Producing message 99
Thread-6 going to consume
0 consumed by Thread-6
Thread-5 going to consume
1 consumed by Thread-5
Thread-4 going to consume
2 consumed by Thread-4
Thread-3 going to consume
3 consumed by Thread-3
Thread-2 going to consume
4 consumed by Thread-2
Thread-1 going to consume
5 consumed by Thread-1
然后应用程序继续运行,在 5 之后没有消费者消费任何消息。
由于wait()
和notifyAll()
是在同一个监视器上创建的sharedMessages
,并且 while 循环继续运行,消费者线程不应该继续运行,或者消费消息吗?
注意:这个问题不是关于有界阻塞队列/典型的生产者消费者。我正在努力更好地理解wait()
和notifyAll
这种行为引起了我的注意。我可能在这里遗漏了一些东西,我正在寻找答案,指出我遗漏了什么,而不是另一种方式。
解决方案
您的Producer
线程锁定队列,然后添加 100 条消息而不释放锁,最后在终止之前释放锁,而不通知任何人。
您的 6 个Consumer
线程将分别使用一条消息,然后调用wait()
.
至此,Producer
线程已经结束,6个Consumer
线程都在等待。
你设想谁会通知他们叫醒他们?
推荐阅读
- react-native - 如何在 React Native 中以 2 列显示图像?
- c++ - 如何在 C++ 中为 if 和 else 语句定义新的行为
- python - 将文件从服务帐户转移到常规帐户
- html - 无法展开导航栏
- decision-tree - 如何在 h2o 中使用决策树算法?
- laravel - 如何在 env 文件中安全保存密码 - Laravel
- firebase - Flutter如何使用Future返回值作为变量
- java - 无法使用弹性搜索构建 Spring Boot 应用程序
- jquery - 与 Datatable 功能交互后,表格正在清空
- typescript - 如何理解 TS 代码解析的结果?