ForkJoinPool主要採用分治算法,將一個大任務分紅一個個小任務,而後將小任務的結果彙總,獲得大任務的結果,下面的demo就是計算1到1000000的總和,經過計算0->4,5->9,10->14...等等,每組的值,而後累加獲得總和。java
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(); //累加子任務的結果 } } } }
業務中常常到了節假日或者活動日,都須要向全部用戶的號碼發送短信,面對龐大的用戶量,若是仍是順序執行發送短信,將會很是耗時,能夠使用ExecutorService線程池併發作,也能夠使用ForkJoinPool作。算法