Реализация 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 ответов
ты называешь 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 на этом.