1. 程式人生 > >Fork/Join框架(一)引言

Fork/Join框架(一)引言

宣告:本文是《 Java 7 Concurrency Cookbook 》的第五章,作者: Javier Fernández González     譯者:許巧輝 校對:方騰飛

在這個章節中,我們將覆蓋:

引言

通常,當你實現一個簡單的併發應用程式,你實現一些Runnable物件和相應的 Thread物件。在你的程式中,你控制這些執行緒的建立、執行和狀態。Java 5引入了Executor和ExecutorService介面及其實現類進行了改進(比如:ThreadPoolExecutor類)。

執行者框架將任務的建立與執行分離。有了它,你只要實現Runnable物件和使用Executor物件。你提交Runnable任務給執行者,它建立、管理執行緒來執行這些任務。

Java 7更進一步,包括一個面向特定問題的ExecutorService介面的額外實現,它就是Fork/Join框架。

這個框架被設計用來解決可以使用分而治之技術將任務分解成更小的問題。在一個任務中,檢查你想要解決問題的大小,如果它大於一個既定的大小,把它分解成更小的任務,然後用這個框架來執行。如果問題的大小是小於既定的大小,你直接在任務中解決這問題。它返回一個可選地結果。以下圖總結了這個概念:

1

沒有公式來確定問題的引數大小,所以你可以根據它的特點來確定一個任務是否可以被細分。你可以參考任務處理元素的大小和預估任務執行時間來確定子任務大小。你需要解決的問題是測試不同的參考大小來選擇最好的一個。你可以將ForkJoinPool作為一種特殊的執行者來考慮。

這個框架基於以下兩種操作:

  • fork操作:當你把任務分成更小的任務和使用這個框架執行它們。
  • join操作:當一個任務等待它建立的任務的結束。

Fork/Join 和Executor框架主要的區別是work-stealing演算法。不像Executor框架,當一個任務正在等待它使用join操作建立的子任務的結 束時,執行這個任務的執行緒(工作執行緒)查詢其他未被執行的任務並開始它的執行。通過這種方式,執行緒充分利用它們的執行時間,從而提高了應用程式的效能。

為實現這個目標,Fork/Join框架執行的任務有以下侷限性:

  • 任務只能使用fork()和join()操作,作為同步機制。如果使用其他同步機制,工作執行緒不能執行其他任務,當它們在同步操作時。比如,在Fork/Join框架中,你使任務進入睡眠,正在執行這個任務的工作執行緒將不會執行其他任務,在這睡眠期間內。
  • 任務不應該執行I/O操作,如讀或寫資料檔案。
  • 任務不能丟擲檢查異常,它必須包括必要的程式碼來處理它們。

Fork/Join框架的核心是由以下兩個類:

  • ForkJoinPool:它實現ExecutorService介面和work-stealing演算法。它管理工作執行緒和提供關於任務的狀態和它們執行的資訊。
  • ForkJoinTask: 它是將在ForkJoinPool中執行的任務的基類。它提供在任務中執行fork()和join()操作的機制,並且這兩個方法控制任務的狀態。通常, 為了實現你的Fork/Join任務,你將實現兩個子類的子類的類:RecursiveAction對於沒有返回結果的任務和RecursiveTask 對於返回結果的任務。

本章有5個指南,告訴你如何使Fork/Join框架有效地工作。