原理
Fork:把一个复杂任务进行分拆,大事化小
Join:把分拆任务的结果进行合并
相关类
ForkJoinPool
分支合并池 类比=> 线程池
ForkJoinTask
ForkJoinTask 类比=> FutureTask
RecursiveTask
递归任务:继承后可以实现递归(自己调自己)调用的任务
例子
需求:计算0-100的和
流程:
首先定义一个常量10,根据等差数列的方法
判断end减begin是否<=常量,若满足,则直接进行计算,
若不满足,则通过(end+begin)/2算出中间值middle,通过middle来将运算分成两个线程来分别处理,
一个处理begin到middle之间的数
另一个处理middle+1到end之间的数
public class ForkJoinDemo{
public static void main(String[] args) throws Exception{
MyTask m = new MyTask(0, 100);
ForkJoinPool threadPool = new ForkJoinPool();
// 递交任务,获得任务的返回值
ForkJoinTask<Integer> threadTask = threadPool.submit(m);
// 因为ForkJoinTask实现了Future接口,所以可以直接使用get方法
System.out.println(threadTask.get());
threadPool.shutdown();
}
}
class MyTask extends RecursiveTask<Integer>{
private static final int START_JOINNUM = 10;
private int begin;
private int end;
private int result;
public MyTask(int begin, int end){
this.begin = begin;
this.end = end;
}
@Override
protected Integer compute(){
if((end - begin) <= START_JOINNUM){
for(int i = begin; i <= end; i++){
result += i;
}
}else{
int middle = (end + begin) / 2;
MyTask m1 = new MyTask(begin, middle);
MyTask m2 = new MyTask(middle + 1, end);
m1.fork();
m2.fork();
result = m1.join() + m2.join();
}
return result;
}
}
异步回调例子
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) throws Exception {
// 没有返回值的异步回调
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
System.out.println(Thread.currentThread().getName() + "没有返回值");
});
completableFuture.get();
// 有返回值的异步回调
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
// 正常执行
System.out.println(Thread.currentThread().getName() + "有返回值");
// 模拟异常
//int i = 10 / 0;
return 1024;
});
System.out.println(integerCompletableFuture.whenComplete((t, u) -> {
// BiConsumer<T, U> 需要传两个参数的消费者接口
System.out.println("t:" + t);
System.out.println("u:" + u);
}).exceptionally(f -> {
// 异常处理
System.out.println("exception" + f.getMessage());
return 4444;
}).get());
}
}