亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

ForkJoin 并發框架介紹

1. 前言

本節帶領大家認識第二個并發框架之 ForkJoin。

本節先介紹 ForkJoin 并發框架的整個體系結構,接著介紹各部分中的核心接口和實現類,下一節中使用 ForkJoin 并發框架實現一個綜合例子,讓大家從整體概念、接口實現、應用有一個較全面的了解。

下面我們正式開始介紹吧。

2. 整體結構介紹

從 JDK 1.7 開始,java 提供了一套大任務分解成小任務并行執行的框架 ForkJoin ,并且在 JDK 1.8 中進一步做了優化。

相比上一節介紹的 Executor 并發框架而言,ForkJoin 框架更傾向于任務拆分并行執行的場合,而 Executor 框架更適合于更一般的任務彼此之間無內在關系的場合。

ForkJoin 框架的基本思想是將一個大任務拆分成多個處理邏輯相同的子任務,最后將這些子任務的結果再匯總起來,從而得到大任務的結果。即在任務處理時,先進行任務切分,然后進行切分后的各子任務的計算,最后做結果合并。擔任子任務還可以繼續進行切分,這需要根據實際情況而定。

整體結構已經了解了,接著我們繼續了解各部分的核心接口和實現類。

3. 核心接口和實現類

整個 ForkJoin 框架的核心接口和實現類很簡潔,羅列如下:

  1. 線程池 ForkJoinPool,代表執行任務的線程池。
  2. 執行線程 ForkJoinWorkerThread,代表 ForkJoinPool 線程池中的一個執行任務的線程。
  3. 任務 ForkJoinTask ,代表運行在 ForkJoinPool 中的任務。

ForkJoin 框架核心接口的使用邏輯如下圖:
圖片描述
下面,我們繼續深入了解各接口和實現類的基本知識。

3.1. ForkJoinPool

ForkJoinPool 代表了此任務的執行器,當采用 ForkJoin 框架執行我們的任務時,首先需要創建一個 ForkJoinPool 對象,所有后繼執行的過程控制都交給此對象完成。代碼舉例:

// 構建任務執行器
ForkJoinPool pool = new ForkJoinPool();
// 提交待執行的任務
ForkJoinTask<T> result = pool.submit(ForkJoinTask類型的對象);
// 開始任務執行并獲取執行結果
result.invoke();

3.2. ForkJoinWorkerThread

ForkJoinWorkerThread 是 ForkJoin 框架中用于執行任務的線程實現。一般情況下我們無需顯式地使用此類,由 ForkJoinPool 類內部自行創建并維護。

3.3. ForkJoinTask

ForkJoinTask 是一個抽象類,定義了任務的主要操作接口。

  1. fork ():在當前線程運行的線程池中再創建提交一個子任務。
  2. join ():當任務完成的時候返回計算結果。
  3. invoke ():開始執行任務,如果必要等待計算完成。

共有兩個子類:

  1. RecursiveAction:提供了無需關心任務執行結果場合下的默認實現
  2. RecursiveTask:提供了最終需獲取任務執行結果的場合下的默認實現

一般我們只需要根據實際情況,選擇繼承上面的兩個子類之一,然后實現自己的邏輯就可以了。代碼舉例:

class myTask extends RecursiveTask<Integer> {
	@Override
	protected Integer compute() {
		// 執行邏輯,可根據情況直接計算返回,也可根據任務大小確定是否繼續拆分子任務
		SumTask left = new myTask(子任務待處理的數據范圍);
		SumTask right = new SumTask(子任務待處理的數據范圍);
		left.fork();
		right.fork();
		return left.join() + right.join();
	}
}

4. 小結

本節帶領大家對 ForkJoin 框架做整體認識,熟悉其最基本骨架內容,先做到有整體的概念。具體 ForkJoin 框架如何使用呢,我們在下一節講述。希望大家在學習過程中,多思考勤練習,早日掌握之。