![](/img/trans.png)
[英]Java implementation of Producer Consumer throws java.lang.IllegalMonitorStateException
[英]Java Producer Consumer IllegalMonitorStateException
我已經使用 java 線程構建了生產者-消費者。 生產者和消費者是兩個不同的 class 指的是單個 LinkedList 和 object 鎖。 下面的實現有什么問題?
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();
方法不遵守其合同:
喚醒正在此對象的監視器上等待的單個線程。 (...)此方法只能由作為該對象監視器所有者的線程調用。
wait
方法也是如此:
此方法只能由作為該對象監視器所有者的線程調用。
TL:博士
您正在對錯誤的鎖(即this
返回的實例的隱式鎖)調用wait
和notify()
)。
將這些調用分別更改為:
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();
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.