Fork/Join框架是Java7提供了的一個用於並行執行任務的框架, 是一個把大任務分割成若干個小任務,最終彙總每一個小任務結果後獲得大任務結果的框架。html
Fork/Join使用兩個類:java
ForkJoinPool是一個執行ForkJoinTask的ExecutorService,ForkJoinPool提供no-ForkJoinTask客戶端提交的入口點,以及管理和監視操做。算法
ForkJoinPool與其餘類型的ExecutorService的不一樣之處主要在於使用工做竊取:池中的全部線程都嘗試查找和執行提交給池的任務和/或由其餘活動任務建立的任務(若是不存在則最終阻止等待工做)。當大多數任務產生其餘子任務時(如大多數ForkJoinTasks),以及從外部客戶端向池提交許多小任務時,這能夠實現高效處理。特別是在構造函數中將asyncMode設置爲true時,ForkJoinPools也可能適用於從未加入的事件樣式任務。api
static commonPool()適用於大多數應用程序,common pool由未顯式提交到指定池的任何ForkJoinTask使用。使用common pool一般會減小資源使用(其線程在不使用期間緩慢回收,並在後續使用時恢復)。oracle
而後咱們寫一個demo,這裏DoTask繼承了RecursiveAction,裏面的有start和end,還有最多處理list中THRESHOLD條數據。框架
而後咱們運行一下:async
輸出:函數
對於須要單獨或自定義pool的應用程序,可使用給定的目標並行度級別構造ForkJoinPool;默認狀況下,等於可用處理器的數量。。線程
默認狀況下,common pool使用默認參數構造,但能夠經過設置三個系統屬性來控制它們:翻譯
java.util.concurrent.ForkJoinPool.common.parallelism
- 並行級別,這是一個非負整數。java.util.concurrent.ForkJoinPool.common.threadFactory
- ForkJoinPool.ForkJoinWorkerThreadFactory 類
java.util.concurrent.ForkJoinPool.common.exceptionHandler
- Thread.UncaughtExceptionHandler 類
此實現將最大運行線程數限制爲32767.嘗試建立大於最大數量的池會致使IllegalArgumentException。
僅當pool關閉或內部資源耗盡時,此實現纔會拒絕提交的任務(即經過拋出RejectedExecutionException)。
下面摘錄一段(https://www.cnblogs.com/wanly3643/p/3956801.html),等我看了Doug Lea大神的,再寫一點:
仔細看了Doug Lea的那篇文章:A Java Fork/Join Framework 中關於Work-Stealing的部分,下面列出該算法的要點(基本是原文的翻譯):
1. 每一個Worker線程都維護一個任務隊列,即ForkJoinWorkerThread中的任務隊列。
2. 任務隊列是雙向隊列,這樣能夠同時實現LIFO和FIFO。
3. 子任務會被加入到原先任務所在Worker線程的任務隊列。
4. Worker線程用LIFO的方法取出任務,也就後進隊列的任務先取出來(子任務老是後加入隊列,可是須要先執行)。
5. Worker線程的任務隊列爲空,會隨機從其餘的線程的任務隊列中拿走一個任務執行(所謂偷任務:steal work,FIFO的方式)。
6. 若是一個Worker線程遇到了join操做,而這時候正在處理其餘任務,會等到這個任務結束。不然直接返回。
7. 若是一個Worker線程偷任務失敗,它會用yield或者sleep之類的方法休息一下子,再嘗試偷任務(若是全部線程都是空閒狀態,即沒有任務運行,那麼該線程也會進入阻塞狀態等待新任務的到來)。
Doug Lea
參考:
http://ifeve.com/java-fork-join-framework/#more-35602
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html
http://gee.cs.oswego.edu/dl/papers/fj.pdf()
有什麼討論的內容,能夠加我公衆號: