`

ForkAndJoin实践

阅读更多

Java的并发编程模型中,有个Fork-Join框架,目的是将大的任务分解成小的任务进行计算,然后再把每个小任务的计算结果汇总。

Fork / Join 框架提供了两个可供继承的子类

1,RecursiveAction 用以分解没有计算结果的任务

2,RecursiveTask    用以分解有计算结果的任务

 

接下来计算一个1加到100的程序,体会一下Fork/Join框架的使用

 

首先定义一个任务类CountTask类,因为是要计算结果,因此继承RecursiveTask类,主要是实现其compute方法,这里设置的阀值THRESHOLD值为10,表示每个任务计算的加数的个数最多为10个,接下来就是将任务根据阀值分组,并对每个分组进行计算

 

package com.luchi.thread.forkAndJoin;

import java.util.concurrent.RecursiveTask;

public class CountTask extends RecursiveTask<Integer>{

	private static final int THRESHOLD=10;//设置阀值
	private int start;
	private int end;
	
	public CountTask(int start, int end) {
		super();
		this.start = start;
		this.end = end;
	}

	@Override
	protected Integer compute() {
		// TODO Auto-generated method stub
		int sum=0;
		//看任务是不是在阀值以下
		boolean canComputs=(end-start+1)<=THRESHOLD;
		if(canComputs){
			for(int i=start;i<=end;i++){
				sum+=i;
			}
			return sum;
		}else{
			int size=end-start+1;
			int taskNum;
			if(size%THRESHOLD==0){
				taskNum=size/THRESHOLD;
			}else{
				taskNum=size/THRESHOLD+1;
			}
			for(int i=1;i<=taskNum;i++){
				
				int groupBegin=start+(i-1)*THRESHOLD;
				int groupEnd=Math.min(groupBegin+THRESHOLD-1, end);
				CountTask childTask=new CountTask(groupBegin, groupEnd);
				childTask.fork();
				int childCount=childTask.join();
				sum+=childCount;
			}
			return sum;
		}
	}

}

 

 

看一下测试程序TestForkAndJoin类,fork/join需要使用ForkJoinPool容器,这个容器负责执行每个task

 

package com.luchi.thread.forkAndJoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;

public class TestForkAndJoin {
	
	
	
	
	public static void main(String[]args){
		
		ForkJoinPool forkJoinPool=new ForkJoinPool();
		CountTask task=new CountTask(1,100);
		Future<Integer> result=forkJoinPool.submit(task);
		try {
			System.out.println(result.get());
		} catch (InterruptedException | ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	

}

 

其实这个模型和FutureTask使用方法差不多,不同的是,FutureTask是单线程使用,而ForkJoinPool里面保持了一个ForkJoinTask数组用来保存多个任务,同时ForkJoinWorkerThread用来执行任务,我的理解就是ForkJoin框架提供了一个多线程的执行环境用来执行多个任务而已,而其join方法和其他地方的join方法相同

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics