记录与分享,你我共成长 -from caicongyang
1.Fork/Join
分解(Fork)操作:当需要将一个任务拆分成更小的多个任务时,在框架中执行这些任务;合并(Join)操作:当一个主任务等待其创建的多个子任务的完成执行;
2.核心类
ForkJoinPool:这个类实现了ExecutorService接口和工作窃取算法(Work-Stealing Algorithm)。它管理工作者线程,并提供任务的状态信息,以及任务的执行信息。
ForkJoinTask:这个类是一个将在ForkJoinPool中执行的任务的基类。Fork/Join框架提供了在一个任务里执行fork()和join()操作的机制和控制任务状态的方法。通常,为了实现Fork/Join任务,需要实现一个以下两个类之一的子类。
RecursiveAction:用于任务没有返回结果的场景。
RecursiveTask:用于任务有返回结果的场景。
3.demo
实现一个1..n的整数相加的demo
package com.caicongyang.newfeatures;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
/**
* fork/join框架
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
/**
* get()和join()有两个主要的区别:
* join()方法同步返回,不能被中断。如果你中断调用join()方法的线程,这个方法将抛出InterruptedException异常。如果任务抛出任何未受检异常,
* get()方法异步返回将返回一个ExecutionException异常,而join()方法将返回一个RuntimeException异常。
*/
//同步返回结果
//Future<Integer> result = pool.submit(new CountTask(0, 2000));
//System.out.println(result.get());
//异步返回结果
CountTask task = new CountTask(0, 2000);
pool.execute(task);
pool.shutdown();
Integer count = task.join();
System.out.println(count);
}
}
/**
* 计算1..n相加总和的简单demo
* @author Administrator
*
*/
class CountTask extends RecursiveTask<Integer>{
/**
* serialID
*/
private static final long serialVersionUID = 1L;
//边界值
private static final int THRESHOLD = 50;
private int start;
private int end;
public CountTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
boolean canCompute = (end - start) <= THRESHOLD;
if (canCompute) {
for (int i = start; i <= end; i++)
sum += i;
} else {
int mid = (start + end) / 2;
CountTask t1 = new CountTask(start, mid);
CountTask t2 = new CountTask(mid+1, end);
t1.fork();
t2.fork();
sum = t1.join() + t2.join();
}
return sum;
}
}
如果你觉得本文对你有帮助,可以扫描下面的微信二维码,请我喝杯水咯!