本文源碼:GitHub·點這裡 || GitEE·點這裡
Java提供Fork/Join架構用于并行執行任務,核心的思想就是将一個大任務切分成多個小任務,然後彙總每個小任務的執行結果得到這個大任務的最終結果。
這種機制政策在分布式資料庫中非常常見,資料分布在不同的資料庫的副本中,在執行查詢時,每個服務都要跑查詢任務,最後在一個服務上做資料合并,或者提供一個中間引擎層,用來彙總資料:

核心流程:切分任務,子產品任務異步執行,單任務結果合并;在程式設計裡面,通用的代碼不多,但是通用的思想卻随處可見。
基于1+2..+100的計算案例示範Fork/Join架構基礎用法。
ForkJoinPool:線程池最大的特點就是分叉(fork)合并(join)模式,将一個大任務拆分成多個小任務,并行執行,再結合工作竊取算法提高整體的執行效率,充分利用CPU資源。
ForkJoinTask:運作在ForkJoinPool的一個任務抽象,可以了解為類線程但是比線程輕量的實體,在ForkJoinPool中運作的少量ForkJoinWorkerThread可以持有大量的ForkJoinTask和它的子任務,同時也是一個輕量的Future,使用時應避免較長阻塞或IO。
繼承子類:
RecursiveAction:遞歸無傳回值的ForkJoinTask子類;
RecursiveTask:遞歸有傳回值的ForkJoinTask子類;
核心方法:
fork():在目前線程運作的線程池中建立一個子任務;
join():子產品子任務完成的時候傳回任務結果;
invoke():執行任務,也可以實時等待最終執行結果;
任務拆分
ForkJoinPool基于分治算法,将大任務不斷拆分下去,每個子任務再拆分一半,直到達到最門檻值設定的任務粒度為止,并且把任務放到不同的隊列裡面,然後從最底層的任務開始執行計算,并且往上一層合并結果,這樣用相對少的線程處理大量的任務。
工作竊取算法
大任務被分割為獨立的子任務,并且子任務分别放到不同的隊列裡,并為每個隊列建立一個線程來執行隊列裡的任務,假設線程A優先把配置設定到自己隊列裡的任務執行完畢,此時如果線程E對應的隊列裡還有任務等待執行,空閑的線程A會竊取線程E隊列裡任務執行,并且為了減少竊取任務時線程A和被竊取任務線程E之間的發生競争,竊取任務的線程A會從隊列的尾部擷取任務執行,被竊取任務線程E會從隊列的頭部擷取任務執行。
工作竊取算法的優點:線程間的競争很少,充分利用線程進行并行計算,但是在任務隊列裡隻有一個任務時,也可能會存在競争情況。
在後端系統的業務開發中,可用做權限校驗,批量定時任務狀态重新整理等各種功能場景:
如上圖,假設資料的主鍵id分段如下,資料場景可能是資料源的連接配接資訊,或者産品有效期類似業務,都可以基于線程池任務處理:
權限校驗
基于資料源的連接配接資訊,判斷資料源是否可用,例如:判斷連接配接是否可用,使用者是否有庫表的讀寫權限,在資料源多的情況下,基于線程池快速校驗。
狀态重新整理
在定時任務中,經常見到狀态類的重新整理操作,例如判斷産品是否在有效期範圍内,在有效期範圍之外,把資料置為失效狀态,都可以利用線程池快速處理。
推薦閱讀:Java并發系列
序号
文章标題
01
Java并發:線程的建立方式,狀态周期管理
02
Java并發:線程核心機制,基礎概念擴充
03
Java并發:多線程并發通路,同步控制
04
Java并發:線程間通信,等待/通知機制
05
Java并發:悲觀鎖和樂觀鎖機制
06
Java并發:Lock機制下API用法詳解