併發編程模式

一、future模式

在網上購物時,提交訂單後,在收貨的這段時間裏無需一直在家裏等候,可以先幹別的事情。類推到程序設計中時,當提交請求時,期望得到答覆時,如果這個答覆可能很慢。傳統的是一直等待到這個答覆收到時再去做別的事情,但如果利用Future設計模式就無需等待答覆的到來,在等待答覆的過程中可以幹其他事情。

future模式核心思想就是異步調用,去除了主函數的等待時間,並使得原本需要等待的時間段可以用於處理其他業務邏輯。

下面是時序圖,左邊是傳統的單線程執行,右邊使用了future模式。

 

我們通過synchronized結合wait()和notify()、併發包下的鎖都可以實現future模式,不過JDK已經爲我們提供了future模式的實現,位於java.util.concurrent併發包下。

具體使用方法可參考文章:https://www.2cto.com/kf/201411/351903.html

 

二、Master-Worker模式

Master-Worker 模式是常用的並行計算模式。它的核心思想是系統由兩類進程協作工作:Master 進程和 Worker 進程。Master 負責接收和分配任務,Worker 負責處理子任務。當各個 Worker 子進程處理完成後,會將結果返回給 Master , 由 Master 進行歸納和總結。其好處是能將一個大任務分解成若干個小任務,並行執行,從而提高系統的吞吐量。

 

在Master端往往會有如下的內容:

1、一個盛放任務的容器,一般使用隊列來保證先添加的任務先執行,因爲在下面參考文章的例子中,任務在main方法中被直接一口氣全部提交過來,所以worker不需要在沒有任務可以取的時候而阻塞等待新任務,也就是不牽涉到阻塞,所以在這裏推薦使用非阻塞的線程安全隊列ConcurrentLinkedQueue性能更好,參考文章中也是使用了這種隊列。

2、一個盛放worker的線程集合,worker就是用來執行任務的,所以就是個子線程,所以可以使用HashMap<String, Thread>來盛放,key是每個worker線程的標識。

3、一個盛放任務結果的集合,和盛放worker的線程集合不同,worker的線程集合就是在初始化Master時需要指定有多少個worker的,所以是一併初始化好的,沒有併發也就沒有線程安全問題,而任務結果的集合會被多個worker訪問,需要線程安全的容器才行,推薦ConcurrentHashMap。

每個worker端往往會有如下的內容:

1、Master裏盛放任務的容器的引用,因爲需要獲取任務。

2、Master裏盛放任務結果集合,因爲需要把處理完的任務結果放進去。

Master-Worker模式的實現可參考文章:http://blog.csdn.net/lv_fq/article/details/70853315

 

三、生產者-消費者模式

生產者-消費者模式是一個經典的多線程設計模式。它爲多線程間的協作提供了良好的解決方案。 在生產者-消費者模式中,通常由兩類線程,即若干個生產者線程和若干個消費者線程。生產者線程負責提交用戶請求,消費者線程則負責具體處理生產者提交的任務。生產者和消費者之間則通過共享內存緩衝區進行通信。

 

生產者-消費者模式可以通過線程間通信的方式實現,例如通過synchronized結合wait()和notify()、併發包下的鎖都可以。但最好的方式是使用阻塞隊列來實現,阻塞隊列又是線程安全的這樣不僅高效而且實現非常簡單,將阻塞隊列作爲存放數據的內存緩衝區,通過調用阻塞隊列的阻塞方法put()和take(),開發者不需要寫困惑的wait-nofity代碼去實現通信。

生產者-消費者模式的實現可參考文章:http://blog.csdn.net/yujin753/article/details/45723175

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章