Reactor 模型(一)基本併發編程模型

Reactor 模型(一)基本併發編程模型

Netty 系列目錄 (http://www.javashuo.com/article/p-hskusway-em.html)html

在講解 Reactor 線程模型以前,咱們須要先對基本併發編程模型:串行工做模型、併發工做模型進行講解。java

串行工做者模型和並行工做者模型關注的是將任務劃分爲 2 個階段:一是任務的接受階段;二是任務的處理階段。而 Reactor 線程模型關注的是上述第二個階段:任務在處理的過程當中,繼續劃分爲多個步驟進行處理。react

1、串行模型

咱們以一個典型的任務處理流程,來講明爲何要將任務的接受流程與處理流程劃分開來數據庫

併發操做

在這個例子中,一個 Worker 線程來處理用戶提交的任務,任務的處理步驟粗略的分爲:接受任務和處理任務兩個階段。當 Worker 接受到一個任務以後,就馬上進行處理,也就是說任務接受和任務處理是在同一個 Worker 線程中進行的,沒有進行區分。這樣作存在一個很大的問題是,必需要等待某個 Task 處理完成以後,才能接受處理下一個 Task。編程

而一般狀況下,任務的處理過程會比任務的接受流程慢得多。例如在處理任務的時候,咱們可能會須要訪問遠程數據庫,這屬於一種網絡 IO。一般狀況下 IO 操做是比較耗時的,這直接影響了下一個任務的接受,並且一般在 IO 操做的時候,CPU 是比較空閒的,白白浪費了資源。網絡

所以咱們能夠考慮將任務的接受與處理分爲兩個線程進行處理,一個只負責接受任務,一個只負責處理任務。併發

這就演化出了第一個線程模型:串行工做者模型。以下所示:異步

串行模型

在這種狀況下,接受任務的線程稱之爲 Accept Thread,其將接受到的任務放到一個任務隊列中,所以能當即返回接受下一個任務。而 Worker 線程不斷的從這個隊列中取出任務進行異步執行。線程

目前這種狀況存在一個很大的問題,在於任務處理的太慢,致使隊列裏積壓的任務數量越來愈大,任務不能獲得及時的執行。因此咱們能夠用多個 Worker Thread 來處理任務。這就是串行工做者模型的併發版本-並行工做者模型。設計

2、並行模型

在並行工做者模型中,有一個 Accpet Thread,多個 Worker Thread,由於 Worker Thread 的功能都相同,因此咱們一般會將其劃分到一個組中(Worker Thread Group)。

在具體實現上,並行工做者線程模型有兩種設計方式,如下分別進行介紹。

2.1 基於公共任務隊列

並行工做者線程模型設計方式一:基於公共任務隊列

accept Thread 將接受到的任務放到任務隊列中,Worker Thread group 中的多個 Worker Thread 並行的從公共的隊列中拉取任務進行處理。

並行模型-公共任務隊列

熟悉java線程池 的用戶可能已經發現,能夠用ThreadPoolExecutor 來實現右半部分的功能,由於ThreadPoolExecutor 就是多個線程從一個公共的任務隊列中拉取任務進行執行。經過在main線程中接受任務,將任務提交到線程池中,便可以完成上述線程模型。

2.2 每一個 Worker Thread 維護本身的任務隊列

在第一種方式中,因爲多個Worker線程同時從一個公共的任務隊列中拉取任務進行處理,所以必需要進行加鎖,於是影響了效率。所以又有了下面一種設計方式:Reactor Thread直接將任務轉發給各個 Worker Thread,每一個 Worker Thread 內部維護一個隊列來處理,以下圖

並行模型-私有任務隊列

這種方式的設計,避免的鎖競爭,由於每一個 Worker Thread 都從各自的隊列中取出任務進行執行。實際上,Netty 的實現中,就是爲每一個 Worker Thread 維護了一個隊列。

須要注意的是:因爲如今是 Accpet Thread 直接給過個 Worker Thread 轉發任務,任務分配的平均的責任就落到了 Reactor Thread 的身上。


天天用心記錄一點點。內容也許不重要,但習慣很重要!

相關文章
相關標籤/搜索