gpt4 book ai didi

Java 生产者消费者 IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-12-03 12:45:21 25 4
gpt4 key购买 nike

我已经使用 java 线程构建了生产者-消费者。生产者和消费者是两个不同的类,指的是单链表和对象锁。下面的实现有什么问题?

Item Produced by Thread-0 Item 1
Item Consumed by Thread-1 Item 1

Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at ProducerConsumer$Producer.produce(ProducerConsumer.java:35)
at ProducerConsumer$Producer.run(ProducerConsumer.java:19)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at ProducerConsumer$Consumer.consume(ProducerConsumer.java:63)
at ProducerConsumer$Consumer.run(ProducerConsumer.java:50)
at java.lang.Thread.run(Thread.java:745)

代码实现

import java.util.LinkedList;

public class ProducerConsumer {
LinkedList<Integer> items = new LinkedList<>();
Object lock = new Object();
int capacity = 10;
public static void main(String[] args) {
ProducerConsumer m = new ProducerConsumer();
Thread p = new Thread(m.new Producer());
Thread c = new Thread(m.new Consumer());
p.start();
c.start();
}

class Producer implements Runnable{

@Override
public void run() {
produce();
}

public void produce(){
int value =0;
while(true){
synchronized (lock){
while(items.size() == capacity){
try{
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
items.add(++value);
System.out.println("Item Produced by "+Thread.currentThread().getName()+" Item "+value);
notify();
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}

}
}
}
}

class Consumer implements Runnable{
@Override
public void run() {
consume();
}
public void consume(){
while (true){
synchronized (lock){
while (items.size() == 0){
try{
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("Item Consumed by "+Thread.currentThread().getName()+" Item "+items.remove());
notify();
}
}
}
}
}

最佳答案

Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at ProducerConsumer$Producer.produce(ProducerConsumer.java:35)
at ProducerConsumer$Producer.run(ProducerConsumer.java:19)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at ProducerConsumer$Consumer.consume(ProducerConsumer.java:63)
at ProducerConsumer$Consumer.run(ProducerConsumer.java:50)
at java.lang.Thread.run(Thread.java:745)

这是因为对 notify(); 方法的调用不遵守其 contract: 的事实。

Wakes up a single thread that is waiting on this object's monitor.(...)This method should only be called by a thread that is the owner ofthis object's monitor.

同样适用于 wait 方法:

This method should only be called by a thread that is the owner of this object's monitor.

TL:DR

您在错误的锁上调用waitnotify()( this 实例的隐式返回

分别将这些调用更改为:

lock.notify();lock.wait();

基于所提供代码的运行示例:

import java.util.LinkedList;

public class ProducerConsumer {
final LinkedList<Integer> items = new LinkedList<>();
final Object lock = new Object();
final int capacity = 10;
public static void main(String[] args) {
ProducerConsumer m = new ProducerConsumer();
Thread p = new Thread(m.new Producer());
Thread c = new Thread(m.new Consumer());
p.start();
c.start();
}

class Producer implements Runnable{

@Override
public void run() {
try {
produce();
} catch (InterruptedException e) { /** do something **/ }
}

public void produce() throws InterruptedException {
int value =0;
while(true){
synchronized (lock){
while(items.size() == capacity)
lock.wait();
items.add(++value);
System.out.println("Item Produced by "+Thread.currentThread().getName()+" Item "+value);
lock.notify();
Thread.sleep(1000);
}
}
}
}

class Consumer implements Runnable{
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) { /** do something **/ }
}
public void consume() throws InterruptedException {
while (true){
synchronized (lock){
while (items.size() == 0)
lock.wait();
System.out.println( "Item Consumed by "
+Thread.currentThread().getName()+
" Item "+items.remove());
lock.notify();
}
}
}
}
}

关于Java 生产者消费者 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66016112/

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