您好,欢迎来到钮旅网。
搜索
您的当前位置:首页ForkJoinPool和ForkJoinTask联用,示例解析

ForkJoinPool和ForkJoinTask联用,示例解析

来源:钮旅网

ForkJoinPool

ForkJoin算法执行大概流程

任务的拆分 fork,直到判断任务已经足够细粒度(原子任务),底层用到递归 类似微服务项目

由此我们可以看出对于ForkJoinPool来说一个大任务会细分多个子任务,每个子任务可以继续划分多个子任务直到不能划分为主,当各个阶段的任务都执行完此时会合并各个阶段返回的数据组成最终的返回值 相比于ThreadPoolExecutor来说 同一个任务ForkJoinPool可以被多个线程执行而ThreadPoolExecutor只能被一个线程执行.

工作窃取

每个线程执行的任务存在一个队列当中,当某一线程执行完自己的任务就会去窃取其他线程的任务,由于双向队列的原因每个线程的任务队列都是互通的在这里插入代码片

ForkJoinTask

当我们使用callable或者是runnable 时任务窃取不会生效 此时只有实现ForkJoinTask类的子任务才会生效

示例

10-100的计算

public class MyTest4 {

    public static void main(String[] args) {
        //不显示线程数量 默认是CPU核心数*2
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        MyTask myTask = new MyTask(1,100 );
        Integer invoke = forkJoinPool.invoke(myTask);

        System.out.println(invoke);

        forkJoinPool.shutdown();
    }
}

class MyTask extends RecursiveTask<Integer> {

    //两数之间间隔数
    private int limit = 4;
    //首
    private int firstIndex;
    //尾
    private int lastIndex;

    public MyTask(int firstIndex, int lastIndex) {
        this.firstIndex = firstIndex;
        this.lastIndex = lastIndex;
    }

    @Override
    protected Integer compute() {

        int result = 0;

        int gap = lastIndex - firstIndex;

        boolean flag = gap <= limit;

        if (flag) {
            System.out.println(Thread.currentThread().getName());

            for (int i = firstIndex; i <= lastIndex; i++) {
                result += i;
            }
        } else {//不符合要求对任务进行拆分
            int middleIndex = (firstIndex + lastIndex) / 2;

            MyTask leftTask = new MyTask(firstIndex, middleIndex);
            MyTask rightTask = new MyTask(middleIndex + 1, lastIndex);

            //执行递归操作 ForkJoinTask的静态方法 内部会执行我们重写的compute
//            invokeAll(leftTask, rightTask);

//            //同上
//            invokeAll(leftTask);
//            invokeAll(rightTask);

            //同上
            ArrayList<MyTask> objects = new ArrayList<>();
            objects.add(rightTask);
            objects.add(leftTask);
            invokeAll(objects);
            /*
                join() 获取任务执行汇总结果
             */
            int leftTaskResult = leftTask.join();
            int rightTaskResult = rightTask.join();

            result = leftTaskResult + rightTaskResult;
        }

        return result;
    }
}

参看

参看

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- niushuan.com 版权所有 赣ICP备2024042780号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务