【问题标题】:Java Producer Consumer IllegalMonitorStateExceptionJava 生产者消费者 IllegalMonitorStateException
【发布时间】:2021-02-02 19:10:04
【问题描述】:

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

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();
                }
            }
        }
    }
}

【问题讨论】:

    标签: java multithreading performance parallel-processing producer-consumer


    【解决方案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)
    

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

    唤醒正在此对象的监视器上等待的单个线程。 (...) 这个方法只能被拥有的线程调用 此对象的监视器。

    同样适用于wait 方法:

    该方法只能由作为该对象的监视器所有者的线程调用。

    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();
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 2019-05-24
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多