Java生产者消费者非法监视器状态异常

Java生产者消费者非法监视器状态异常,java,multithreading,performance,parallel-processing,producer-consumer,Java,Multithreading,Performance,Parallel Processing,Producer Consumer,我已经使用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.IllegalMonitorStateExc

我已经使用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();
                }
            }
        }
    }
}
import java.util.LinkedList;
公共类生产者消费者{
LinkedList items=新建LinkedList();
对象锁=新对象();
国际通行能力=10;
公共静态void main(字符串[]args){
ProducerConsumer m=新的ProducerConsumer();
线程p=新线程(m.newproducer());
线程c=新线程(m.new Consumer());
p、 start();
c、 start();
}
类生成器实现了Runnable{
@凌驾
公开募捐{
产生();
}
公共产品{
int值=0;
while(true){
已同步(锁定){
while(items.size()=容量){
试一试{
等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
项目。添加(++值);
System.out.println(“由“+Thread.currentThread().getName()+”Item“+value”生成的项);
通知();
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
}
类使用者实现Runnable{
@凌驾
公开募捐{
消费();
}
公共消费(){
while(true){
已同步(锁定){
而(items.size()==0){
试一试{
等待();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
System.out.println(“由”+Thread.currentThread().getName()+“Item”+items.remove()消耗的项”);
通知();
}
}
}
}
}
这是由于调用
notify()方法不符合its的要求

唤醒等待此对象监视器的单个线程。 (...) 此方法只能由作为的所有者的线程调用 此对象的监视器。

这同样适用于
wait
方法:

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

TL:DR

您正在错误的锁上调用
wait
notify()

分别将这些调用更改为:

lock.notify()
锁定。等待()

基于提供的代码的运行示例:

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();
                }
            }
        }
    }
}
import java.util.LinkedList;
公共类生产者消费者{
最终LinkedList项=新建LinkedList();
最终对象锁=新对象();
最终int容量=10;
公共静态void main(字符串[]args){
ProducerConsumer m=新的ProducerConsumer();
线程p=新线程(m.newproducer());
线程c=新线程(m.new Consumer());
p、 start();
c、 start();
}
类生成器实现了Runnable{
@凌驾
公开募捐{
试一试{
产生();
}catch(InterruptedException e){/**做点什么**/}
}
public void product()引发InterruptedException{
int值=0;
while(true){
已同步(锁定){
while(items.size()=容量)
lock.wait();
项目。添加(++值);
System.out.println(“由“+Thread.currentThread().getName()+”Item“+value”生成的项);
lock.notify();
睡眠(1000);
}
}
}
}
类使用者实现Runnable{
@凌驾
公开募捐{
试一试{
消费();
}catch(InterruptedException e){/**做点什么**/}
}
public void consume()引发InterruptedException{
while(true){
已同步(锁定){
而(items.size()==0)
lock.wait();
System.out.println(“消耗的项目”
+Thread.currentThread().getName()+
“Item”+items.remove());
lock.notify();
}
}
}
}
}
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();
                }
            }
        }
    }
}