Java 多線程中的任務分解機制-ForkJoinPool詳解

一、任務分解問題和ForkJoinPool簡介

       在多線程併發編程中,有時候會遇到將大任務分解成小任務再併發執行的場景。Java 8新增的ForkJoinPool很好的支持了這個問題。

       ForkJoinPool是一種支持任務分解的線程池,當提交給他的任務“過大”,他就會按照預先定義的規則將大任務分解成小任務,多線程併發執行。

      一般要配合可分解任務接口ForkJoinTask來使用,ForkJoinTask有兩個實現它的抽象類:RecursiveAction和RecursiveTask,其區別是前者沒有返回值,後者有返回值。

          

         下面通過具體代碼,來示範兩個問題:(1)怎麼定義可分解的任務類 (2)如何使用ForkJoinPool

package com;

import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

public class Main {
	
	
    /**定義一個可分解的的任務類,繼承了RecursiveAction抽象類
     * 必須實現它的compute方法
     */
    public static class myTask extends RecursiveAction {

		private static final long serialVersionUID = 1L;
		//定義一個分解任務的閾值——50,即一個任務最多承擔50個工作量
    	int THRESHOLD=50;
    	//任務量
    	int task_Num=0;
		myTask(int Num){
			this.task_Num=Num;
		}
		@Override
		protected void compute() {
			if(task_Num<=THRESHOLD){
				System.out.println(Thread.currentThread().getName()+"承擔了"+task_Num+"份工作");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}else{
				//隨機解成兩個任務
				Random m=new Random();
				int x=m.nextInt(50);
						
				myTask left=new myTask(x);
				myTask right=new myTask(task_Num-x);
				
				left.fork();
				right.fork();
			}
		}
    }

	public static void main(String[] args) throws Exception {
        //創建一個支持分解任務的線程池ForkJoinPool
		ForkJoinPool pool=new ForkJoinPool();
		myTask task=new myTask(178);
		
		pool.submit(task);
		pool.awaitTermination(20, TimeUnit.SECONDS);//等待20s,觀察結果
		pool.shutdown();
	}
}


運行結果如下:

ForkJoinPool-1-worker-1承擔了34份工作
ForkJoinPool-1-worker-2承擔了34份工作
ForkJoinPool-1-worker-3承擔了20份工作
ForkJoinPool-1-worker-0承擔了14份工作
ForkJoinPool-1-worker-0承擔了48份工作
ForkJoinPool-1-worker-3承擔了7份工作
ForkJoinPool-1-worker-2承擔了21份工作


二、總結

     通過運行結果可以發現,ForkJoinPool支持開啓新線程執行被分解的任務,同時也會複用以前的老線程去承擔被分解的任務,具備線程池的通用屬性。

    更多線程池的資料,請參考本人的博文: Java 中7種線程池詳解+示例代碼


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章