ForkJoin
Fork拆分
Join合并
实际上就是一个递归
ForkJoinTask:我们要使用 Fork/Join 框架,首先需要创建一个 ForkJoin 任务。
该类提供了在任务中执行 fork 和 join 的机制。通常情况下我们不需要直接集
成 ForkJoinTask 类,只需要继承它的子类,Fork/Join 框架提供了两个子类:
a.RecursiveAction:用于没有返回结果的任务
b.RecursiveTask:用于有返回结果的任务
• ForkJoinPool:ForkJoinTask 需要通过 ForkJoinPool 来执行
• RecursiveTask: 继承后可以实现递归(自己调自己)调用的任务
直接看案例
场景: 生成一个计算任务,计算 1+2+3…+1000,每 100 个数切分一个子任务
package com.atguigu.test;
import java.util.concurrent.RecursiveTask;
/**
* 递归累加
*/
public class TaskExample extends RecursiveTask<Long> {
private int start;
private int end;
private long sum;
/**
* 构造函数
* @param start
* @param end
*/
public TaskExample(int start, int end){
this.start = start;
this.end = end; }
/**
* The main computation performed by this task.
*
* @return the result of the computation
*/
@Override
protected Long compute() {
System.out.println("任务" + start + "=========" + end + "累加开始");
//大于 100 个数相加切分,小于直接加
if(end - start <= 100){
for (int i = start; i <= end; i++) {
//累加
sum += i; } }else {
//切分为 2 块
int middle = start + 100;
//递归调用,切分为 2 个小任务
TaskExample taskExample1 = new TaskExample(start, middle);
TaskExample taskExample2 = new TaskExample(middle + 1, end);
//执行:异步
taskExample1.fork();
taskExample2.fork();
//同步阻塞获取执行结果
sum = taskExample1.join() + taskExample2.join();
}
//加完返回
return sum; } }
实际上就是一个递归,然后计算方法就是重写computer方法,
如果两个数相差100以内,就直接加,如果相差100以上,就大分成小,然后一直递归下去
TaskExample taskExample1 = new TaskExample(start, middle);
TaskExample taskExample2 = new TaskExample(middle + 1, end);
而独有的就是这两步
//执行:异步
taskExample1.fork();
taskExample2.fork();
//同步阻塞获取执行结果
sum = taskExample1.join() + taskExample2.join();
}
public class ForkJoinPoolDemo {
/**
* 生成一个计算任务,计算 1+2+3.........+1000
* @param args
*/
public static void main(String[] args) {
//定义任务
TaskExample taskExample = new TaskExample(1, 1000);
//定义执行对象
ForkJoinPool forkJoinPool = new ForkJoinPool();
//加入任务执行
ForkJoinTask<Long> result = forkJoinPool.submit(taskExample);
//输出结果
try {
System.out.println(result.get());
}catch (Exception e){
e.printStackTrace();
}finally {
forkJoinPool.shutdown();
}
} }
而关键就是 执行的时候,forkJoin要放在forkJoinPool池子里面执行。
所以得先创建一个ForkJoinPool()对象
ForkJoinPool forkJoinPool = new ForkJoinPool();
然后用它的sumbit方法执行forkjoin对象,海恩那个返回值
ForkJoinTask<Long> result = forkJoinPool.submit(taskExample);
但是要获得这个值,要通过get()方法
System.out.println(result.get());