1.简介
ForkJoinPool主要采用分治算法,将一个大任务分成一个个小任务,然后将小任务的结果汇总,得到大任务的结果,下面的demo就是计算1到1000000的总和,通过计算0->4,5->9,10->14...等等,每组的值,然后累加得到总和。
2.ForkJoinPool使用demo
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
@Slf4j
public class ForkJoinPoolTest {
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
//当构造函数中没有传入要创建的线程数目时候,ForkJoinPool默认创建的线程数目为物理cpu数目
int size = 1000000;
long forkJoinStartTime = System.currentTimeMillis();
long[] numbers = LongStream.rangeClosed(1, size).toArray();
Long result = forkJoinPool.invoke(new MyRecursiveTask(numbers, 0, size-1)); //创建总任务,并调用
long forkJoinEndTime = System.currentTimeMillis();
System.out.println("running time:" + (forkJoinEndTime - forkJoinStartTime));
System.out.println("result:"+result);
forkJoinPool.shutdown();//关闭forkJoinPool池
}
private static class MyRecursiveTask extends RecursiveTask<Long> { //RecursiveTask 带返回值,RecursiveAction不带返回值
private long[] numbers;
private int start;
private int end;
public MyRecursiveTask(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if (start - end <= 5) {//当起始数量小于等于5时候进行求和
Long total = 0L;
for (int i = start; i <= end; i++) {
total += numbers[i];
}
return total;
} else {
int middle = (start + end) / 2;
MyRecursiveTask left = new MyRecursiveTask(numbers, start, middle); //分别创建两个子任务,也可根据需要创建多个子任务
MyRecursiveTask right = new MyRecursiveTask(numbers, middle + 1, end);
MyRecursiveTask.invokeAll(left,right);
return left.join() + right.join(); //累加子任务的结果
}
}
}
}
3.ForkJoinPool实战
业务中经常到了节假日或者活动日,都需要向所有用户的号码发送短信,面对庞大的用户量,如果还是顺序执行发送短信,将会非常耗时,可以使用ExecutorService线程池并发做,也可以使用ForkJoinPool做。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。