Реализация Java производителя потребитель бросает java.ленг.IllegalMonitorStateException

import java.util.LinkedList;
import java.util.Queue;

class Producer extends PubSub implements Runnable{

    @Override
    public void run() {
        synchronized(queue){
            if (queue.size() == 99){
                try { 
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.add(2);
            try{
                Thread.sleep(1000);
            }
            catch (InterruptedException e){
                e.printStackTrace();
            }
            notify();
            }
        }       
}


class Consumer extends PubSub implements Runnable{

    @Override
    public void run() {
        synchronized(queue){
            if(queue.isEmpty()){
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }   
            }
            System.out.println(queue.poll());
        }

    }

}
public class PubSub {
    static Integer QUEUE_SIZE = 100;
    Queue<Integer> queue = new LinkedList<Integer>();
    public static void main(String[] args) {
        Producer producer = new Producer();
        Consumer consumer = new Consumer();
        Thread producerThread = new Thread(producer);
        Thread consumerThread = new Thread(consumer);
        producerThread.start();
        consumerThread.start();
        System.out.println("Started both the threads");
    }

}

Я получаю java.lang.IllegalMonitorStateException на wait() часть. Я хочу знать, что я делаю не так. Есть идеи??

полное исключение, которое я получаю следующим образом.

Exception in thread "Thread-1" Started both the threads
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at Consumer.run(PubSub.java:36)
    at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at Producer.run(PubSub.java:23)
    at java.lang.Thread.run(Thread.java:745)

4 ответов


Я думаю, что ваш код работает ...

как указано JB Nizet, вы должны вызвать wait и уведомить о


ты называешь wait(), что эквивалентно this.wait(), но вы не держите монитор this. Вы держите монитор на queue. Так и должно быть queue.wait(). (то же самое для notify()).


Проверьте Javadoc для IllegalMonitorStateException

https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html

исключение возникает при попытке wait() (или notify()) на объекте, который вы не держите монитор; вы синхронизировали в очереди, но попытались wait() on this, который не является очередью, а скорее runnable. Меняется wait() до queue.wait() и notify() to queue.notify() должны работать.


поток может вызывать notify () или wait () только на объекте, на котором он уже приобрел блокировку. В вашем потоке программы есть блокировка объекта очереди, а затем ваш поток вызывает wait на этом.