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
uj5u.com熱心網友回復:
java.lang.IllegalMonitorStateException 同步代碼塊不是同一個鎖uj5u.com熱心網友回復:
是不是有了阻塞佇列就不需要notify,wait去實作阻塞了?轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/263113.html
標籤:Web 開發
上一篇:Java web
下一篇:對spring框架的一點理解
