java程序中的监视器陷入死锁
我试图用Java中的monitor解决单个消费者/生产者的问题,代码如下。当我运行这段代码时,它最终会被卡住。最典型的情况是消费者调用java程序中的监视器陷入死锁,java,concurrency,producer-consumer,Java,Concurrency,Producer Consumer,我试图用Java中的monitor解决单个消费者/生产者的问题,代码如下。当我运行这段代码时,它最终会被卡住。最典型的情况是消费者调用wait(),然后生产者继续生产,但无法通知消费者(尽管它将调用notify())。我不知道为什么会这样。Java代码: import java.util.*; class Monitor { int length; int size; int begin, end; int queue[]; private static
wait()
,然后生产者继续生产,但无法通知消费者(尽管它将调用notify()
)。我不知道为什么会这样。Java代码:
import java.util.*;
class Monitor {
int length;
int size;
int begin, end;
int queue[];
private static Random randGenerator;
public Monitor() {}
public Monitor(int length) {
this.length = length;
this.size = 0;
begin = end = 0;
queue = new int[length];
randGenerator = new Random(10);
}
public synchronized void produce() throws InterruptedException {
while(size == length) {
System.out.println("Producer waiting");
wait();
}
int produced = randGenerator.nextInt();
size++;
queue[end] = produced;
end = (end + 1) % length;
System.out.println("Produce element " + produced + " size "+size);
// When size is not 1, no thread is blocked and therefore don't need to notify
if(size == 1) {
System.out.println("Notify consumer");
notify();
}
}
public synchronized void consume() throws InterruptedException {
while(size == 0) {
System.out.println("Consumer waiting, size " + size);
wait();
}
size--;
System.out.println("Consume element " + queue[begin] + " size " + size);
begin = (begin + 1) % length;
if(size == length - 1) {
System.out.println("Notify producer");
notify();
}
}
}
class Producer implements Runnable {
Monitor producer;
public Producer(Monitor m) {
producer = m;
}
@Override
public void run() {
producer = new Monitor();
System.out.println("Producer created");
try {
while(true) {
producer.produce();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
Monitor consumer;
public Consumer(Monitor m) {
consumer = m;
}
@Override
public void run() {
System.out.println("Consumer created");
consumer = new Monitor();
try {
while(true) {
consumer.consume();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class monitorTest {
public static void main(String args[]) {
Monitor monitor = new Monitor(10);
Thread t1 = new Thread(new Producer(monitor));
Thread t2 = new Thread(new Consumer(monitor));
t1.start();
t2.start();
}
}
当每个线程的控件进入
product()
或consume()
方法时,大小和长度都为零,因此两个线程都在等待另一个线程通知。打破这一点,您的代码将摆脱死锁
public synchronized void produce() throws InterruptedException {
while(size == length) { // size is 0 and length is 0; so wait
System.out.println("Producer waiting");
wait();
}
之所以会发生这种情况,是因为您在生产者和消费者对象的
run()
方法中调用了一个默认构造函数
class Producer implements Runnable {
Monitor producer;
public Producer(Monitor m) {
producer = m;
}
@Override
public void run() {
producer = new Monitor(); // REMOVE THIS
class Consumer implements Runnable {
Monitor consumer;
public Consumer(Monitor m) {
consumer = m;
}
@Override
public void run() {
System.out.println("Consumer created");
consumer = new Monitor(); // AND REMOVE THIS
希望这有帮助 假设有两个消费者先来,两个都输入
wait()
。然后一个制作人来了,发布一个notify()
。紧接着,在任何消费者被叫醒之前,另一个制作人来了,添加了一个项目,但没有任何通知。现在,只有一个消费者会被叫醒。@ZhongYu感谢您的评论。我在主函数中只创建了一个生产者和一个消费者,程序仍然无法正常运行。为什么呢?请注意,我已经提到该程序是针对单个生产者/消费者问题的。您不应该再次调用new Monitor()
-删除这两行后,只需使用main()@ZhongYu中创建的监视器即可,它工作正常。谢谢(这对我来说是个多么愚蠢的错误啊哈哈)。由于您没有发布答案(确实不需要…),我会将anacron的答案标记为已接受。但我会将monitor.length初始化为10(monitor monitor=new monitor(10)
),因此长度不应为0,而应为10。我错了吗?我在语句开头之前打印了大小和长度。我得到了尺寸=0,长度=0。
class Producer implements Runnable {
Monitor producer;
public Producer(Monitor m) {
producer = m;
}
@Override
public void run() {
producer = new Monitor(); // REMOVE THIS
class Consumer implements Runnable {
Monitor consumer;
public Consumer(Monitor m) {
consumer = m;
}
@Override
public void run() {
System.out.println("Consumer created");
consumer = new Monitor(); // AND REMOVE THIS