Java 多線程中的生産者消費者模型是一個很經典的示例。
什麼是生産者消費者模型呢?
所謂的生産者消費者模型,是通過一個容器來解決生産者和消費者的強耦合問題。
舉個例子,我們去工廠拿貨,工廠也在給我們生産,這就必然存在一個中間容器,我們可以把這個容器想象成
是一個倉庫。當我們想要拿貨的時候,我們就去倉庫檢視有沒有生産好的貨物,如果貨架是空的,工廠就要生
産貨物,此時我們作為消費者就需要等待工廠生産商品;當工廠生産的商品太多了爆滿了倉庫,工廠就可以通
知作為消費者的我們去倉庫拿貨,這樣不停循環。在這個循環過程中,我們不是直接接觸工廠的,而是去倉庫
拿貨,工廠也并不是生産好了商品就直接給到我們,而是将生産好的商品放在倉庫中,工廠和我們是不會進行
直接接觸的。所謂的倉庫,我們可以想象成一個queue(隊列),這個隊列就是把我們和工廠給解耦,這就是
生産者消費者模型。
生産者消費者模型能解決什麼問題?
顯而易見,生産者消費者模型能将生産者和消費者徹底解耦,并且,我們可以不在乎生産者的生産速度,以及
消費者的消費速度。
生産者消費者模型代碼示例:
先定義商品類
package goods;
/**
* 商品類
*/
public class Goods {
private String name; // 商品的名稱
private int price; // 商品的價格
public Goods(String name,int price){
this.name = name;
this.price = price;
}
public String toString(){
return "name="+name+",price="+price;
}
}
生産者:
package goods;
/**
* 生産者
* fazcube
*/
public class Producer implements Runnable{
private Goods goods;
@Override
public void run() {
while (true){
try {
//控制一下間隔時間
Thread.sleep(1000);
synchronized (Start.queue){
goods = new Goods("商品",5);
//如果倉庫(queue)的大小大于等于倉庫最大的數量,那麼就讓線程wait
if(Start.queue.size() >= Start.MAX_COUNT){
System.out.println(Thread.currentThread().getName()+"說:倉庫爆滿啦!快點來拿貨!");
Start.queue.wait();
}else{
//如果倉庫還有位置,那麼就繼續生産商品。
Start.queue.add(goods);
System.out.println(Thread.currentThread().getName()+"生産了一個商品");
}
//将等待的線程喚醒
Start.queue.notify();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
消費者:
package goods;
/**
* 消費者
* fazcube
*/
public class Consumer implements Runnable{
@Override
public void run() {
while (true){
try {
//控制一下間隔時長
Thread.sleep(1000);
synchronized (Start.queue){
//如果
if(!Start.queue.isEmpty()){
Start.queue.poll();
System.out.println(Thread.currentThread().getName()+"消費了一個商品,還剩:"+Start.queue.size()+"個");
}else{
System.out.println(Thread.currentThread().getName()+"說:倉庫裡面沒有貨啦!快點生産!");
Start.queue.wait();
}
//将等待的線程喚醒
Start.queue.notify();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
啟動類:
package goods;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
public class Start {
/** 設定最大存貨量 */
public static int MAX_COUNT = 5;
/** 消費者的數量 */
public static int CONSUMER_COUNT = 5;
/** 生産者的數量 */
public static int PRODUCER_COUNT = 5;
/** 建立一個queue來存放商品 */
public static Queue<Goods> queue = new ArrayBlockingQueue<>(MAX_COUNT);
public static void main(String[] args) {
Consumer consumer = new Consumer();
Producer producer = new Producer();
for(int i=0;i<PRODUCER_COUNT;i++){
Thread thread = new Thread(producer,"生産者"+i+"号");
thread.start();
}
for(int m=0;m<CONSUMER_COUNT;m++){
Thread thread = new Thread(consumer,"消費者"+m+"号");
thread.start();;
}
}
}
啟動截圖:

如有錯誤還請指教,謝謝!