gpt4 book ai didi

java - 生产者/消费者死锁多线程Java

转载 作者:行者123 更新时间:2023-11-30 08:08:57 25 4
gpt4 key购买 nike

我正在尝试使用多线程解决 Java 中的生产者/消费者问题,但我一直陷入僵局,我无法弄清楚原因。

BoundedBuffer.java

public class BoundedBuffer {
private final int[] buffer;
private final int N;
private int in = 0;
private int out = 0;
private int itemCount = 0;

public BoundedBuffer(int size) {
N = size + 1;
buffer = new int[N];
}

public void insert(Producer producer, int item) {
synchronized (producer) {
while ( (in + 1) % N == out) {
try {
producer.wait();
} catch (InterruptedException e) {}
}
buffer[in] = item;
in = (in + 1) % N;
itemCount++;
}

public int remove(Consumer consumer) {
synchronized (consumer) {
while (in == out) {
try {
consumer.wait();
} catch (InterruptedException e) {}
}

int item = buffer[out];
buffer[out] = null;
out = (out + 1) % N;
itemCount--;

return item;
}
}
}

Producer.java

public class Producer extends Thread {
private int total = 0;
private BoundedBuffer buffer;
private int uniqueItem = 0;

public Producer(int total, BoundedBuffer b) {
this.total = total;
this.buffer = b;
}

public void run() {
for (int i = 0; i < quota; i++) {
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {}
buffer.insert(this, uniqueItem++);
this.notifyAll();
}
}
}

消费者.java

public class Consumer extends Thread {
private int total = 0;
private BoundedBuffer buffer;

public Consumer(int total, BoundedBuffer b) {
this.total = total;
this.buffer = b;
}

public void run() {
for (int i = 0; i < total; i++) {
try {
Thread.sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {}
buffer.remove(this);
this.notifyAll();
}
}
}

这段代码会运行一段时间,当我设置调试时(“这个生产者正在尝试插入这个项目......”)我看到一个很好的模式出现,但我时不时地得到这个错误:

Exception in thread "Thread-2" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Consumer.run(Consumer.java:19)

然后我在那之后的某个时间发生了死锁。

我认为我的问题是由于我正在同步的 key ,producerconsumer 实例。我不确定还有什么我可以同步方法,这是最让我难过的。我相信我可以为每个消费者/生产者共享一个 key ,但我不确定它是如何工作的。

最佳答案

您应该在 BoundedBuffer 本身上进行同步,并在同步块(synchronized block)内使用 wait 来释放锁并等待,直到另一个线程通知正在 hibernate 的线程。

本教程中有一个完整的示例: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

另外,请注意,您现在可以使用 BlockingQueue 以更简单的方式实现消费者-生产者模式。

这里有 BlockingQueue 的文档,显示了一个更简单的 Consumer-Producer 实现: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

关于java - 生产者/消费者死锁多线程Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32814788/

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