Fork/Join框架的浅析

Fork/Join框架的主要功能

Fork/Join框架主要完成了两件事情:

  1. 任务分割:首先把大的任务分割成足够小的子任务;
  2. 执行任务并合并结果:分割的子任务分别存放到双端队列中,然后几个启动线程风别从双端队列中获取任务执行,子任务执行完成的结果都存放在另一个队列里,启动一个线程从队列里取数据,然后合并这些数据;

Fork/Join框架的实现原理

ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成:

  1. ForkJoinTask数组负责将存放的程序提交给ForkJoinPool;
  2. ForkJoinWorkerThread负责执行这些任务
    当调用ForkJoinTask的fork方法时,程序会把任务放在ForkJoinWorkerThread的putTask的workQueue中,异步的执行这个任务,然后立即返回结果

实例演示

  1. ForkJoinTask:我们使用Fork/Join框架首先要创建一个ForkJoin任务,需继承其子类:
    a. RecursiveAction:用于无返回值的任务
    b. RecuriveTask:用于又返回值的任务
  2. ForkJoinPool:ForkJoinTask的执行环境
    分割出的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部。当一个工作线程的队列里暂时没有任务时,它会随机从其他工作线程的队列尾部获取一个任务(工作窃取算法
//首先继承其子类,这个是有返回值的,所以继承RecursiveTask
public class CountTask extends RecursiveTask<Integer> {
	private static final int THREAD_HOLD = 2;
	
	private int satrt;
	private int end;
	
	public  CountTask(int start,int end){
		this.start = start;
		this.end = end;
	}

	@Override
	protected Integer compute(){
		int sum = 0;
		boolean flag = (end - start)<=THREAD_HOLD;
		if(flag){
			for(int i = start;i < end;i++){
				sum += i; 
			}
		} else {
			int middle = (start + end)/2;
			CountTask one = new CountTask(start,middle);
			CountTask two = new CountTask(middle+1,end);
			//执行子任务
			one.fork();
			two.fork();
			//获取子任务执行结果
			int oResult = one.join();
			int tResult = two.join();
			sum = oResult + tResult;
		}
		return sum;
	}
}

public class ExeWork {
	public static void main(String[] args){
		ForkJoinPool pool = new ForkJoinPool ();
		CountTask task = new CountTask(1,4);
		Future<Integer> result = pool.submit(task);
		try{
			//合并这些数据
			System.ot.println(result.get());
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

Fork/Join框架的异常处理

ForkJoinTask在执行任务的时候可能会抛出异常,但主线程无法直接铺获异常,所以ForkJoinTask提供了isCompletedAbnormally()方法来检查任务是否已将抛出异常或已被取消了,并可以通过ForkJoinTask的getException方法获取异常.

猜你喜欢

转载自blog.csdn.net/weixin_43935907/article/details/86726559