我正在学习多线程。
我尝试用Java实现生产者消费者问题。它工作正常。 但是如果我删除通知调用,程序就会进入死锁状态。为什么?
当队列大小变为0时,它会发生死锁。理想情况下,当大小变为0时,应该在消费者内部调用wait,生产者应该开始工作。
import java.io.*;
import java.util.*;
class Consumer implements Runnable{
Queue<Integer> q;
int n;
public void run() {
while(true){
synchronized (q) {
while(q.size()==0){
try {
System.out.println("q.size="+q.size());
q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("item consumed="+q.poll());
q.notify();
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Consumer(Queue<Integer> queue,int n){
q=queue;
this.n=n;
}
}
class Producer implements Runnable{
Queue<Integer> q;
int n;
public void run() {
int x=1;
while(true){
synchronized (q) {
while(q.size()==n){
try {
q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("item produced="+x+" q.size="+q.size());
q.add(x++);
q.notify();
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Producer(Queue<Integer> queue,int n){
q=queue;
this.n=n;
}
}
public class App
{
public static void main( String[] args ) throws InterruptedException
{
int n=100;
Queue<Integer> q=new LinkedList<Integer>();
Thread t1=new Thread(new Producer(q, n));
Thread t2=new Thread(new Consumer(q, n));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
最佳答案
您需要通知,因为当一个线程处于等待状态时,因为队列为空或已满,如果其他线程在放入队列为空且获取队列已满后发出通知,则进入运行状态。 put q.wait(10);所以你的代码不会陷入死锁,因为过了一段时间它会检查 while 循环条件。 在上述用例中使用通知始终是最佳实践
关于java - 多线程中Notify方法的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45336741/