當前位置:
首頁 > 知識 > Fork/Join框架學習筆記(三)

Fork/Join框架學習筆記(三)

Fork/Join框架學習筆記(三)

多線程

《Fork/Join框架學習筆記(一)》

《Fork/Join框架學習筆記(二)》


一些類

先說最重要的兩個:

ForkJoinPool池類

用來執行任務(ForkJoinTask),生成新的工作線程(ForkJoinWorkerThread)。

負責工作線程間的工作竊取。

線程池的個數一般是CPU核數。

執行任務有三個方法:

invoke:同步執行帶返回值的任務。ForkJoinTask.invoke。

submit:非同步執行帶返回值(Future)的任務。ForkJoinTask.fork(ForkJoinTasks are Futures)。

execute:非同步執行不帶返回值的任務。ForkJoinTask.fork。

(大家可以看前文的兩個例子)

ForkJoinTask任務類

ForkJoinTask就是用來執行的任務類,主要是工作是大任務的分割(Fork)以及結果的合併(Join),結合之前的例子可看,這是我們主要的編碼區。

不過真正工作中我們是不用這個類的,而是用它的兩個子類:

RecursiveAction,沒有返回值。

RecursiveTask,有返回值。

ForkJoinTask有幾個重要方法:

fork(),非同步執行當前Task。

invoke(),同步執行,等待任務完成並返回結果。

invokeAll(),同步執行給的Task,等待所有任務完成並返回結果。

join(),獲取返回值。不可中斷,否則會拋出InterruptedException。如果運行的任務拋出異常,返回RuntimeException。

get(),獲取返回值。如果運行的任務拋出異常,返回ExecutionException。

說說invokeAll(task1,task2)這個方法。具體代碼不再附上。其步驟是:

1、 執行task2的fork()。fork()代碼步驟不再附上,步驟如下:

1)先通過push ()將任務放入當前線程的工作隊列的Top位置。注意之前提到的「工作竊取」,放在Top位置可以優先讓本線程處理。

額外再說一句,有的資料上說用pushTask()。我看的是JDK8源碼,用push()。

2)如果隊列滿了,擴容。

3)如果隊列中的任務比較少(<=1),就執行ForkJoinPool.signalWork()方法,喚醒一個空閑的線程,或新建一個線程去立即執行。

由上可知,如果隊列中任務較多,Task就會存在workQueue中,可供其他工作線程進行「工作竊取」。

2、 task1調用doInvoke()方法,直接同步執行。先判斷任務狀態,如果狀態為<0(正常、取消、異常等),則說明任務執行完畢,返回狀態。否則就執行任務,然後判斷是否結束,如果結束就把狀態置為「正常」,否則就等待任務完成。

3、 task1執行完,task2調用doJoin()方法。join()方法也主要是調用doJoin(),其主要工作就是判斷任務的狀態,如果狀態為<0(正常、取消、異常等),則說明任務已經執行完畢,返回狀態。否則就通過tryUnpush()從隊尾(隊列的Top位置)取任務執行。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Java個人學習心得 的精彩文章:

Fork/Join框架學習筆記(二)

TAG:Java個人學習心得 |