Java中实现Producer-Consumer时的java.lang.IllegalMonitorStateException

时间:2016-01-09 21:26:46

标签: java multithreading

我正在尝试用Java实现Producer使用者问题。我正在尝试实现一种功能,其中Producer将项目推送到堆栈并等待消费者使用它。消费者在尝试使用它之前等待堆栈有一些值。

这应该在无限循环中发生。问题是代码只运行一次然后我得到以下异常:

Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at com.nik.threads.Producer.run(Producer.java:28)
java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at com.nik.threads.Consumer.run(Consumer.java:28)

问题出在notify()电话上。我知道问题正在发生,因为线程并不知道要通知谁,因为它不知道等待的线程。但我无法实现它。以下是我的代码:

Producer.java:

class Producer extends Thread{
    private Stack<Integer> stack;
    public Producer(Stack<Integer> stack){
        this.stack=stack;
    }

    @Override
    public void run() {
        for(int i=0;;i++){
            if(!stack.isEmpty())
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        stack.push(i);
        try {
            sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        notify();
    }   }
}

Consumer.java:

 class Consumer extends Thread{
        private Stack<Integer> stack;

        public Consumer(Stack<Integer> stack){
            this.stack=stack;
        }

        @Override
        public void run() {
            for(;;){
                if(stack.isEmpty())
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                System.out.println("Consumed:"+stack.pop());
                try {
                    sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

ProducerConsumer.java:

import java.util.Stack;

public class ProducerConsumer {

    public static void main(String[] args) throws InterruptedException {
        Stack<Integer> stack=new Stack<>();
        Producer p=new Producer(stack);
        Consumer c=new Consumer(stack);
        p.start();
        c.start();
    }
}

1 个答案:

答案 0 :(得分:0)

您需要在您呼叫等待的监视器上进行同步并在

上进行通知
synchronized(this) wait();

synchronized(this) notify();

(在你的情况下)

(还有一些其他问题,比如,总是检查循环中的等待条件并使用专用的监视器对象,而不是等待并通知,并使用notifyAll而不是notify)