ForkJoinPool使用

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 { //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做。

你可能感兴趣的:(多线程)