1. 程式人生 > >Java多線程_生產者消費者模式1

Java多線程_生產者消費者模式1

多線程 ren 範例 結果 div 之間 trace left 平衡

生產者消費者模型
具體來講,就是在一個系統中,存在生產者和消費者兩種角色,他們通過內存緩沖區進行通信,生產者生產消費者需要的資料,消費者把資料做成產品。生產消費者模式如下圖。(圖片來自網絡,侵刪!)

技術分享圖片

生產者消費者模型的實現
  生產者是一堆線程,消費者是另一堆線程,內存緩沖區可以使用List數組隊列,數據類型只需要定義一個簡單的類就好。關鍵是如何處理多線程之間的協作。這其實也是多線程通信的一個範例。
  在這個模型中,最關鍵就是內存緩沖區為空的時候消費者必須等待,而內存緩沖區滿的時候,生產者必須等待。其他時候可以是個動態平衡。值得註意的是多線程對臨界區資源的操作時候必須保證在讀寫中只能存在一個線程,所以需要設計鎖的策略。


具體實現:

import java.util.LinkedList;

public class ProductorConsumerDemo {
    LinkedList<Integer> lists = new LinkedList<>(); // 定義存放物品的倉庫
    int size = 10; // 定倉庫的大小
    // 生產物品
    public synchronized void add(Integer i) { // 這裏對臨界資源的訪問貫穿了整個方法,synchronized可以直接加到方法上
        if (lists.size() == size) { //
首先判斷還能不能生產? 也就是容量到了size嗎? try { this.wait(); // 不需要的生產 ,就等待 } catch (InterruptedException e) { e.printStackTrace(); } } else { lists.add(i); // 把生產出來的物品放進倉庫 this.notifyAll(); // 喚醒消費者線程來消費 } }
// 消費 public synchronized int remove() { if (lists.size() == 0) { // 判斷有沒有物品 try { this.wait(); // 如果沒有物品就等待, 釋放鎖 } catch (InterruptedException e) { e.printStackTrace(); } } else { int i = lists.removeFirst(); // 有物品,就拿走一個 if (lists.size() == 0) // 如果拿到了最後一個 { this.notifyAll(); // 通知生產者生產物品 } return i; } return -1; } public static void main(String[] args) { ProductorConsumerDemo pcd = new ProductorConsumerDemo(); new Thread(new Runnable() { int count = 1; @Override public void run() { while (true) { int i = count++; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } pcd.add(i); System.out.println(Thread.currentThread().getName() + " 生產了第 " + i + " 個物品,還有" + pcd.lists); } } }, "生產者 ").start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(110); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 消費了第 " + pcd.remove() + "個物品"); } } }, "消費者 ").start(); } }

結果:

技術分享圖片

這種方式很麻煩,在我的嚇一跳博客中將介紹一種簡單的實現方法。

Java多線程_生產者消費者模式1