ForkJoinPool
- Java7 提供另一种并行框架: 分解/治理/合并(分治编程)
- 适用于一种特殊任务, 这类任务的计算量不好确定(最小任务可确定)
- 关键类
- ForkJoinPool 任务池
- RecursiveAction
- RecursiveTask
- 代码示例
package thread0418;
import java.time.LocalDateTime;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* 分任务求和
* 使用 java.util.concurrent.ForkJoinPool (分治编程)
* 使用 RecursiveTask (可以递归的任务接口)
* 1) 把任务分解 一直分解直到 分解到上下限差值小于等于5
* 2) 完成任务
* 3) 把结果合并
*/
public class ForkJoinPoolDemo1 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建执行线程池
ForkJoinPool pool = new ForkJoinPool();
// ForkJoinPool pool = new ForkJoinPool(4); // parallelism
// 创建任务
SumTask111 task = new SumTask111(1, 100000000);
// 提交任务
ForkJoinTask<Long> result = pool.submit(task);
do {
System.out.printf(LocalDateTime.now() + " => " + "Main: PoolActiveThreadCount:%d" + "\n", pool.getActiveThreadCount());
System.out.printf(LocalDateTime.now() + " => " + "Main: 并行度(PoolParallelism): %d" + "\n", pool.getParallelism());
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!task.isDone());
// 输出结果
System.out.println(LocalDateTime.now() + " => " + result.get().toString());
}
}
class SumTask111 extends RecursiveTask<Long> {
private int start;
private int end;
public SumTask111(int start, int end) {
this.start = start;
this.end = end;
}
public static final int threadHold = 5;
@Override
protected Long compute() {
long sum = 0L;
// 如果任务足够小, 直接执行
boolean canCompute = (end - start) <= threadHold;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum = sum + i;
}
} else {
// 任务大于阈值, 分裂为 2 个任务
int middle = (start + end) / 2;
SumTask111 subTask1 = new SumTask111(start, middle);
SumTask111 subTask2 = new SumTask111(middle + 1, end);
invokeAll(subTask1, subTask2);
Long sum1 = subTask1.join();
Long sum2 = subTask2.join();
// 结果合并
sum = sum1 + sum2;
}
return sum;
}
}