11.9-全棧Java筆記: 線程並發協作(生產者/消費者模式)
多線程環境下,我們經常需要多個線程的並發和協作。這個時候,就需要了解一個重要的多線程並發協作模型“生產者消費者模式”。
什麽是生產者?
生產者指的是負責生產數據的模塊(這裏模塊可能是:方法、對象、線程、進程)。
什麽是消費者?
消費者指的是負責處理數據的模塊(這裏模塊可能是:方法、對象、線程、進程)。
什麽是緩沖區?
消費者不能直接使用生產者的數據,它們之間有個“緩沖區”。生產者將生產好的數據放入“緩沖區”,消費者從“緩沖區”拿要處理的數據。
圖119a
緩沖區是實現並發的核心,緩沖區的設置有3個好處
1. 實現線程的並發協作
有了緩沖區以後,生產者線程只需要往緩沖區裏面放置數據,而不需管消費者消費的情況;同樣,消費者只需要從緩沖區拿數據處理即可,也不需管生產者生產的情況。
2. 解耦了生產者和消費者
生產者不需要和消費者直接打交道。
3. 解決忙閑不均,提高效率
生產者生產數據慢時,緩沖區仍有數據,不影響消費者消費;消費者處理數據慢時,生產者仍然可以繼續往緩沖區裏面放置數據 。
【示例1】生產者與消費者模式示例
public class TestProduce { public static void main(String[] args) { SyncStack sStack = new SyncStack(); Shengchan sc = Xiaofei xf = new Xiaofei(sStack); sc.start(); xf.start(); } }
class Mantou { //饅頭 int id; Mantou(int id){ this.id=id; } }
class SyncStack { //緩沖區(相當於:饅頭框) int index=0; Mantou[] ms = new Mantou[10];
public synchronized while(index==ms.length){ try { this.wait(); //wait後,線程會將持有的鎖釋放。sleep是即使睡著也持有互斥鎖。 } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); //喚醒在當前對象等待池中等待的第一個線程。notifyAll叫醒所有在當前對象等待池中等待的所有線程。 //如果不喚醒的話。以後這兩個線程都會進入等待線程,沒有人喚醒。 ms[index]=m; index++; } public synchronized Mantou pop(){ while(index==0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); index--; return ms[index]; } }
class Shengchan extends Thread{ //生產者 SyncStack ss = null;
public Shengchan(SyncStack ss) { this.ss=ss; } @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println("造饅頭:"+i); Mantou m = new Mantou(i); ss.push(m); } } }
class Xiaofei extends Thread{ //消費者 SyncStack ss = null;
public Xiaofei(SyncStack ss) { this.ss=ss; } @Override public void run() { for (int i = 0; i < 20; i++) { Mantou m = ss.pop(); System.out.println("吃饅頭:"+i);
} } |
老鳥建議 在實際開發中,尤其是“架構設計”中,會大量使用這個模式。 對於初學者了解即可,如果晉升到中高級開發人員,這就是必須掌握的內容。 |
「全棧Java筆記」是一部能幫大家從零到一成長為全棧Java工程師系列筆記。筆者江湖人稱 Mr. G,10年Java研發經驗,曾在神州數碼、航天院某所研發中心從事軟件設計及研發工作,從小白逐漸做到工程師、高級工程師、架構師。精通Java平臺軟件開發,精通JAVAEE,熟悉各種流行開發框架。
筆記包含從淺入深的六大部分:
A-Java入門階段
B-數據庫從入門到精通
C-手刃移動前端和Web前端
D-J2EE從了解到實戰
E-Java高級框架精解
F-Linux和Hadoop
本文出自 “12931675” 博客,請務必保留此出處http://12941675.blog.51cto.com/12931675/1945770
11.9-全棧Java筆記: 線程並發協作(生產者/消費者模式)