求助java生产者消费者模式,报错了,怎么解决??

过期小朋友、 2021-02-24 10:59:10
package com.bjsxt.chapter17;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author wmr
* @date 2021/2/24
*/
public class Main {
public static void main(String[] args) {
// 创建存放数据的阻塞队列
ArrayBlockingQueue<Drug> drugQueue=new ArrayBlockingQueue<Drug>(4);
// 创建记录生产数量的原子整数
AtomicInteger drugCount=new AtomicInteger(0);
// 创建记录消费数据的原子整数
AtomicInteger consumeCount=new AtomicInteger(0);
// 创建生产者2个
Producer p1=new Producer(drugQueue,drugCount);
p1.setName("producer-1");
Producer p2=new Producer(drugQueue,drugCount);
p2.setName("producer-2");
// 创建消费者3个
Consumer c1=new Consumer(drugQueue,consumeCount);
Consumer c2=new Consumer(drugQueue,consumeCount);
Consumer c3=new Consumer(drugQueue,consumeCount);
c1.setName("consumer-1");
c2.setName("consumer-2");
c3.setName("consumer-3");
// 启动生产者线程,生产数据
p1.start();
p2.start();
// 启动消费者线程,消费数据
c1.start();
c2.start();
c3.start();
// 每隔一分钟查看阻塞队列数据量,生产数量、消费数量
try {
TimeUnit.SECONDS.sleep(1);
int queueSize=drugQueue.size();
int produceCount=drugCount.get();
int consume=consumeCount.get();
System.out.println("队列中有毒品:"+queueSize+",生产者已经生产了:"+produceCount+"," +
"消费者已经消费了:"+consume);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}


package com.bjsxt.chapter17;

/**
* @author wmr
* @date 2021/2/24
*/
public class Drug {
// 编号
private int id;
// 价格
private int price;

public int getId() {
return id;
}

public int getPrice() {
return price;
}

public Drug(int id, int price) {
this.id = id;
this.price = price;
}
}


package com.bjsxt.chapter17;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author wmr
* @date 2021/2/24
*/
public class Producer extends Thread{
// 生产的数量
private AtomicInteger drugCount;
// 保存数据的阻塞队列的引用变量
private ArrayBlockingQueue<Drug> drugQueue;
// 通过构造方法给引用变量赋值
public Producer(ArrayBlockingQueue<Drug> drugQueue,AtomicInteger drugCount){
this.drugQueue=drugQueue;
this.drugCount=drugCount;
}
// 生产数据
@Override
public void run() {
while(true){
try {
boolean add = drugQueue.offer(new Drug(drugCount.incrementAndGet(), ThreadLocalRandom.current().nextInt(10)));
drugCount.incrementAndGet();
notifyAll();
}catch (Exception e){
e.printStackTrace();
try{
wait();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}
}
}


package com.bjsxt.chapter17;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author wmr
* @date 2021/2/24
*/
public class Consumer extends Thread {
// 消费的数量
private AtomicInteger consumeCount;
// 保存数据的阻塞队列的引用变量
private ArrayBlockingQueue<Drug> drugQueue;
// 通过构造方法给变量赋值
public Consumer(ArrayBlockingQueue<Drug> drugQueue,AtomicInteger consumeCount){
this.drugQueue=drugQueue;
this.consumeCount=consumeCount;
}
// 不停地消费数据
@Override
public void run() {
while (true){
try{
Drug drug = drugQueue.poll();
if(null==drug){
wait();
}
useDrug(drug.getPrice());
consumeCount.incrementAndGet();
notifyAll();
}catch (Exception e){
e.printStackTrace();
try{
wait();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}

}
}
// 使用
public void useDrug(int price){
try{
// 价钱越贵使用时间越久
TimeUnit.MILLISECONDS.sleep(price);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}

运行结果:
"C:\Program Files\Java\jdk-11.0.8\bin\java.exe" "-javaagent:D:\software\idea18\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=50566:D:\software\idea18\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath D:\project\workspace\u2vd_cloud\concurrency\01-Thread\target\classes com.bjsxt.chapter17.Main
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:29)
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.notifyAll(Native Method)
at com.bjsxt.chapter17.Producer.run(Producer.java:28)
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.notifyAll(Native Method)
at com.bjsxt.chapter17.Producer.run(Producer.java:28)
Exception in thread "producer-1" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:29)
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Producer.run(Producer.java:32)
Exception in thread "producer-2" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Producer.run(Producer.java:32)
Exception in thread "consumer-2" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:37)
Exception in thread "consumer-1" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:37)
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.notifyAll(Native Method)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:33)
Exception in thread "consumer-3" java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.bjsxt.chapter17.Consumer.run(Consumer.java:37)
队列中有毒品:1,生产者已经生产了:4,消费者已经消费了:1

Process finished with exit code 0
...全文
82 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
bluedream1991 2021-02-24
  • 打赏
  • 举报
回复
java.lang.IllegalMonitorStateException 同步代码块不是同一个锁
过期小朋友、 2021-02-24
  • 打赏
  • 举报
回复
是不是有了阻塞队列就不需要notify,wait去实现阻塞了?

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧