簡體   English   中英

Java Producer Consumer 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返回的實例的隱式鎖)調用waitnotify() )。

將這些調用分別更改為:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM