文档章节

(十九)java多线程之ForkJoinPool

天之妖星
 天之妖星
发布于 2017/05/08 14:24
字数 5088
阅读 6
收藏 1

本人邮箱: kco1989@qq.com
欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代码已经全部托管github有需要的同学自行下载

引言

java 7提供了另外一个很有用的线程池框架,Fork/Join框架

理论

Fork/Join框架主要有以下两个类组成.
* ForkJoinPool 这个类实现了ExecutorService接口和工作窃取算法(Work-Stealing Algorithm).它管理工作者线程,并提供任务的状态信息,以及任务的执行信息
* ForkJoinTask 这个类是一个将在ForkJoinPool执行的任务的基类.

Fork/Join框架提供了在一个任务里执行fork()join()操作的机制和控制任务状态的方法.通常,为了实现Fork/Join任务,需要实现一个以下两个类之一的子类
* RecursiveAction 用于任务没有返回值的场景
* RecursiveTask 用于任务有返回值的场景.

例子 先定个小目标,1亿就太多,先赚个一百万吧

现在你是一个深圳片区的某公司高级销售主管.现在定了一个目标,就是要赚个一百,让你一个人去赚,肯定有难度的.好在有一般手下,把目标缩小,让小弟们去赚,我们坐等拿钱.ok,开始编程

  • 首先我们要定义个赚钱任务 MakeMoneyTask,如果要赚钱的目标小于最小目标,比如十万,那么就自己去完成,否则,就把任务分给小弟们去做.
public class MakeMoneyTask extends RecursiveTask<Integer>{

    private static final int MIN_GOAL_MONEY = 100000;
    private int goalMoney;
    private String name;
    private static final AtomicLong employeeNo = new AtomicLong();
    public MakeMoneyTask(int goalMoney){
        this.goalMoney = goalMoney;
        this.name = "员工" + employeeNo.getAndIncrement() + "号";
    }
    @Override
    protected Integer compute() {
        if (this.goalMoney < MIN_GOAL_MONEY){
            System.out.println(name + ": 老板交代了,要赚 " + goalMoney + " 元,为了买车买房,加油吧....");
            return makeMoney();
        }else{
            int subThreadCount = ThreadLocalRandom.current().nextInt(10) + 2;
            System.out.println(name + ": 上级要我赚 " + goalMoney + ", 有点小多,没事让我" + subThreadCount + "个手下去完成吧," +
                    "每人赚个 " + Math.ceil(goalMoney * 1.0 / subThreadCount) + "元应该没问题...");
            List<MakeMoneyTask> tasks = new ArrayList<>();
            for (int i = 0; i < subThreadCount; i ++){
                tasks.add(new MakeMoneyTask(goalMoney / subThreadCount));
            }
            Collection<MakeMoneyTask> makeMoneyTasks = invokeAll(tasks);
            int sum = 0;
            for (MakeMoneyTask moneyTask : makeMoneyTasks){
                try {
                    sum += moneyTask.get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println(name + ": 嗯,不错,效率还可以,终于赚到 " + sum + "元,赶紧邀功去....");
            return sum;
        }
    }

    private Integer makeMoney(){
        int sum = 0;
        int day = 1;
        try {
            while (true){
                Thread.sleep(ThreadLocalRandom.current().nextInt(500));
                int money = ThreadLocalRandom.current().nextInt(MIN_GOAL_MONEY / 3);
                System.out.println(name + ": 在第 " + (day ++) + " 天赚了" + money);
                sum += money;
                if (sum >= goalMoney){
                    System.out.println(name + ": 终于赚到 " + sum + " 元, 可以交差了...");
                    break;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return sum;
    }
}
  • 最后我们写一个测试类
public class TestMain {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Integer> task = pool.submit(new MakeMoneyTask(1000000));
        do {
            try {
                TimeUnit.MILLISECONDS.sleep(5);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }while (!task.isDone());
        pool.shutdown();
        System.out.println(task.get());

    }
}

运作之后结果如下:

员工0号: 上级要我赚 1000000, 有点小多,没事让我10个手下去完成吧,每人赚个 100000.0元应该没问题…
员工1号: 上级要我赚 100000, 有点小多,没事让我7个手下去完成吧,每人赚个 14286.0元应该没问题…
员工11号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工10号: 上级要我赚 100000, 有点小多,没事让我5个手下去完成吧,每人赚个 20000.0元应该没问题…
员工18号: 老板交代了,要赚 20000 元,为了买车买房,加油吧….
员工9号: 上级要我赚 100000, 有点小多,没事让我3个手下去完成吧,每人赚个 33334.0元应该没问题…
员工23号: 老板交代了,要赚 33333 元,为了买车买房,加油吧….
员工22号: 老板交代了,要赚 20000 元,为了买车买房,加油吧….
员工22号: 在第 1 天赚了31432
员工22号: 终于赚到 31432 元, 可以交差了…
员工21号: 老板交代了,要赚 20000 元,为了买车买房,加油吧….
员工18号: 在第 1 天赚了32005
员工18号: 终于赚到 32005 元, 可以交差了…
员工19号: 老板交代了,要赚 20000 元,为了买车买房,加油吧….
员工23号: 在第 1 天赚了6166
员工21号: 在第 1 天赚了15433
员工19号: 在第 1 天赚了23419
员工19号: 终于赚到 23419 元, 可以交差了…
员工20号: 老板交代了,要赚 20000 元,为了买车买房,加油吧….
员工20号: 在第 1 天赚了10376
员工11号: 在第 1 天赚了11808
员工21号: 在第 2 天赚了31059
员工21号: 终于赚到 46492 元, 可以交差了…
员工8号: 上级要我赚 100000, 有点小多,没事让我4个手下去完成吧,每人赚个 25000.0元应该没问题…
员工26号: 老板交代了,要赚 25000 元,为了买车买房,加油吧….
员工11号: 在第 2 天赚了11902
员工11号: 终于赚到 23710 元, 可以交差了…
员工12号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工23号: 在第 2 天赚了9077
员工20号: 在第 2 天赚了30386
员工20号: 终于赚到 40762 元, 可以交差了…
员工10号: 嗯,不错,效率还可以,终于赚到 174110元,赶紧邀功去….
员工7号: 上级要我赚 100000, 有点小多,没事让我10个手下去完成吧,每人赚个 10000.0元应该没问题…
员工30号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工12号: 在第 1 天赚了31271
员工12号: 终于赚到 31271 元, 可以交差了…
员工26号: 在第 1 天赚了11631
员工13号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工26号: 在第 2 天赚了10160
员工30号: 在第 1 天赚了10786
员工30号: 终于赚到 10786 元, 可以交差了…
员工31号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工31号: 在第 1 天赚了15201
员工31号: 终于赚到 15201 元, 可以交差了…
员工32号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工26号: 在第 3 天赚了32642
员工26号: 终于赚到 54433 元, 可以交差了…
员工27号: 老板交代了,要赚 25000 元,为了买车买房,加油吧….
员工23号: 在第 3 天赚了33072
员工23号: 终于赚到 48315 元, 可以交差了…
员工24号: 老板交代了,要赚 33333 元,为了买车买房,加油吧….
员工24号: 在第 1 天赚了26309
员工24号: 在第 2 天赚了15420
员工24号: 终于赚到 41729 元, 可以交差了…
员工25号: 老板交代了,要赚 33333 元,为了买车买房,加油吧….
员工13号: 在第 1 天赚了33266
员工13号: 终于赚到 33266 元, 可以交差了…
员工14号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工25号: 在第 1 天赚了19270
员工25号: 在第 2 天赚了15842
员工25号: 终于赚到 35112 元, 可以交差了…
员工9号: 嗯,不错,效率还可以,终于赚到 125156元,赶紧邀功去….
员工6号: 上级要我赚 100000, 有点小多,没事让我9个手下去完成吧,每人赚个 11112.0元应该没问题…
员工40号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工32号: 在第 1 天赚了8133
员工32号: 在第 2 天赚了3518
员工32号: 终于赚到 11651 元, 可以交差了…
员工33号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工27号: 在第 1 天赚了23200
员工14号: 在第 1 天赚了6366
员工27号: 在第 2 天赚了10406
员工27号: 终于赚到 33606 元, 可以交差了…
员工28号: 老板交代了,要赚 25000 元,为了买车买房,加油吧….
员工40号: 在第 1 天赚了28078
员工40号: 终于赚到 28078 元, 可以交差了…
员工41号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工41号: 在第 1 天赚了12996
员工41号: 终于赚到 12996 元, 可以交差了…
员工42号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工33号: 在第 1 天赚了29188
员工33号: 终于赚到 29188 元, 可以交差了…
员工34号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工14号: 在第 2 天赚了17712
员工14号: 终于赚到 24078 元, 可以交差了…
员工15号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工28号: 在第 1 天赚了18623
员工28号: 在第 2 天赚了8205
员工28号: 终于赚到 26828 元, 可以交差了…
员工29号: 老板交代了,要赚 25000 元,为了买车买房,加油吧….
员工34号: 在第 1 天赚了30779
员工34号: 终于赚到 30779 元, 可以交差了…
员工35号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工42号: 在第 1 天赚了26164
员工42号: 终于赚到 26164 元, 可以交差了…
员工43号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工43号: 在第 1 天赚了2995
员工29号: 在第 1 天赚了347
员工15号: 在第 1 天赚了33056
员工15号: 终于赚到 33056 元, 可以交差了…
员工16号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工35号: 在第 1 天赚了3639
员工29号: 在第 2 天赚了22909
员工43号: 在第 2 天赚了2289
员工16号: 在第 1 天赚了27836
员工16号: 终于赚到 27836 元, 可以交差了…
员工17号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工43号: 在第 3 天赚了694
员工17号: 在第 1 天赚了16361
员工17号: 终于赚到 16361 元, 可以交差了…
员工1号: 嗯,不错,效率还可以,终于赚到 189578元,赶紧邀功去….
员工2号: 上级要我赚 100000, 有点小多,没事让我2个手下去完成吧,每人赚个 50000.0元应该没问题…
员工49号: 老板交代了,要赚 50000 元,为了买车买房,加油吧….
员工49号: 在第 1 天赚了8599
员工43号: 在第 4 天赚了10008
员工43号: 终于赚到 15986 元, 可以交差了…
员工44号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工29号: 在第 3 天赚了31298
员工29号: 终于赚到 54554 元, 可以交差了…
员工8号: 嗯,不错,效率还可以,终于赚到 169421元,赶紧邀功去….
员工39号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工49号: 在第 2 天赚了8099
员工35号: 在第 2 天赚了164
员工49号: 在第 3 天赚了5518
员工49号: 在第 4 天赚了22441
员工44号: 在第 1 天赚了6091
员工39号: 在第 1 天赚了18813
员工39号: 终于赚到 18813 元, 可以交差了…
员工48号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工44号: 在第 2 天赚了22324
员工44号: 终于赚到 28415 元, 可以交差了…
员工45号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工49号: 在第 5 天赚了28438
员工49号: 终于赚到 73095 元, 可以交差了…
员工50号: 老板交代了,要赚 50000 元,为了买车买房,加油吧….
员工35号: 在第 3 天赚了31797
员工35号: 终于赚到 35600 元, 可以交差了…
员工36号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工50号: 在第 1 天赚了18071
员工45号: 在第 1 天赚了22528
员工45号: 终于赚到 22528 元, 可以交差了…
员工46号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工36号: 在第 1 天赚了26828
员工36号: 终于赚到 26828 元, 可以交差了…
员工37号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工50号: 在第 2 天赚了32422
员工50号: 终于赚到 50493 元, 可以交差了…
员工2号: 嗯,不错,效率还可以,终于赚到 123588元,赶紧邀功去….
员工3号: 上级要我赚 100000, 有点小多,没事让我9个手下去完成吧,每人赚个 11112.0元应该没问题…
员工51号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工46号: 在第 1 天赚了1537
员工46号: 在第 2 天赚了27529
员工46号: 终于赚到 29066 元, 可以交差了…
员工47号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工48号: 在第 1 天赚了24791
员工48号: 终于赚到 24791 元, 可以交差了…
员工38号: 老板交代了,要赚 10000 元,为了买车买房,加油吧….
员工37号: 在第 1 天赚了17587
员工37号: 终于赚到 17587 元, 可以交差了…
员工47号: 在第 1 天赚了23693
员工47号: 终于赚到 23693 元, 可以交差了…
员工6号: 嗯,不错,效率还可以,终于赚到 211717元,赶紧邀功去….
员工5号: 上级要我赚 100000, 有点小多,没事让我7个手下去完成吧,每人赚个 14286.0元应该没问题…
员工60号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工51号: 在第 1 天赚了27189
员工51号: 终于赚到 27189 元, 可以交差了…
员工52号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工38号: 在第 1 天赚了32285
员工38号: 终于赚到 32285 元, 可以交差了…
员工66号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工7号: 嗯,不错,效率还可以,终于赚到 228718元,赶紧邀功去….
员工65号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工65号: 在第 1 天赚了26122
员工65号: 终于赚到 26122 元, 可以交差了…
员工64号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工52号: 在第 1 天赚了19239
员工52号: 终于赚到 19239 元, 可以交差了…
员工53号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工60号: 在第 1 天赚了10433
员工66号: 在第 1 天赚了25993
员工66号: 终于赚到 25993 元, 可以交差了…
员工63号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工60号: 在第 2 天赚了19529
员工60号: 终于赚到 29962 元, 可以交差了…
员工61号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工64号: 在第 1 天赚了6894
员工53号: 在第 1 天赚了13114
员工53号: 终于赚到 13114 元, 可以交差了…
员工54号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工54号: 在第 1 天赚了8237
员工61号: 在第 1 天赚了15878
员工61号: 终于赚到 15878 元, 可以交差了…
员工62号: 老板交代了,要赚 14285 元,为了买车买房,加油吧….
员工63号: 在第 1 天赚了32108
员工63号: 终于赚到 32108 元, 可以交差了…
员工4号: 上级要我赚 100000, 有点小多,没事让我9个手下去完成吧,每人赚个 11112.0元应该没问题…
员工67号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工64号: 在第 2 天赚了30531
员工64号: 终于赚到 37425 元, 可以交差了…
员工75号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工54号: 在第 2 天赚了13562
员工54号: 终于赚到 21799 元, 可以交差了…
员工55号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工55号: 在第 1 天赚了17774
员工55号: 终于赚到 17774 元, 可以交差了…
员工56号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工67号: 在第 1 天赚了24463
员工67号: 终于赚到 24463 元, 可以交差了…
员工68号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工56号: 在第 1 天赚了1677
员工62号: 在第 1 天赚了14266
员工75号: 在第 1 天赚了26532
员工75号: 终于赚到 26532 元, 可以交差了…
员工74号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工68号: 在第 1 天赚了32639
员工68号: 终于赚到 32639 元, 可以交差了…
员工69号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工69号: 在第 1 天赚了9513
员工56号: 在第 2 天赚了9154
员工56号: 在第 3 天赚了289
员工56号: 终于赚到 11120 元, 可以交差了…
员工57号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工62号: 在第 2 天赚了17321
员工62号: 终于赚到 31587 元, 可以交差了…
员工5号: 嗯,不错,效率还可以,终于赚到 199075元,赶紧邀功去….
员工59号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工69号: 在第 2 天赚了17971
员工69号: 终于赚到 27484 元, 可以交差了…
员工70号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工74号: 在第 1 天赚了26270
员工74号: 终于赚到 26270 元, 可以交差了…
员工73号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工70号: 在第 1 天赚了21237
员工70号: 终于赚到 21237 元, 可以交差了…
员工71号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工59号: 在第 1 天赚了4411
员工57号: 在第 1 天赚了3546
员工57号: 在第 2 天赚了29330
员工57号: 终于赚到 32876 元, 可以交差了…
员工58号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工73号: 在第 1 天赚了10674
员工71号: 在第 1 天赚了8821
员工59号: 在第 2 天赚了11887
员工59号: 终于赚到 16298 元, 可以交差了…
员工72号: 老板交代了,要赚 11111 元,为了买车买房,加油吧….
员工58号: 在第 1 天赚了28241
员工58号: 终于赚到 28241 元, 可以交差了…
员工3号: 嗯,不错,效率还可以,终于赚到 187650元,赶紧邀功去….
员工72号: 在第 1 天赚了14371
员工72号: 终于赚到 14371 元, 可以交差了…
员工73号: 在第 2 天赚了14918
员工73号: 终于赚到 25592 元, 可以交差了…
员工71号: 在第 2 天赚了28814
员工71号: 终于赚到 37635 元, 可以交差了…
员工4号: 嗯,不错,效率还可以,终于赚到 236223元,赶紧邀功去….
员工0号: 嗯,不错,效率还可以,终于赚到 1845236元,赶紧邀功去….
1845236

看到没有,员工0号把任务一百万直接分给了10个手下去做,每个手下有继续往下分,最终在七十几号人的努力下,终于完成了目标–一百万.而且还超出八十多万,老板一开心,直接把八十多万分给这七十多个员工分红了.

后记

通过上面这个例子的学习,相信应该很多人都可以掌握ForkJoinPool这个类,它的核心就是要完成某一个目标任务,如果目标任务太大,那么就创建多个子任务.然后一直等待这些子任务完成.最终完成之前定下的目标任务.


打赏

如果觉得我的文章写的还过得去的话,有钱就捧个钱场,没钱给我捧个人场(帮我点赞或推荐一下)
微信打赏支付宝打赏

© 著作权归作者所有

天之妖星
粉丝 1
博文 30
码字总数 58258
作品 0
深圳
高级程序员
私信 提问
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
1
ForkJoinPool 探索

介绍 “分而治之“是理清思路和解决问题的一个重要的方法。大到系统架构对功能模块的拆分,小到归并排序的实现,无一不在散发着分而治之的思想。在实现分而治之的算法的时候,我们通常使用递...

robinhan
01/10
0
0
JAVA基础再回首(三十)——JAVA基础再回首完美结束,感概万千!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/52724939 JAVA基础再回首(三十)——JAVA基础再回首完美结束,感概万千! 经过了几...

Aduroidpc
2016/10/02
0
0
Java线程之fork/join框架

fork/join框架是用多线程的方式实现分治法来解决问题。fork指的是将问题不断地缩小规模,join是指根据子问题的计算结果,得出更高层次的结果。 fork/join框架的使用有一定的约束条件: 1. 除...

legend3
2014/09/25
0
0
Java 8 Stream并行流

流可以并行执行,以增加大量输入元素的运行时性能。并行流ForkJoinPool通过静态ForkJoinPool.commonPool()方法使用公共可用的流。底层线程池的大小最多使用五个线程 - 具体取决于可用物理CPU...

qianmoQ
03/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

驰骋工作流引擎-督查督办系统

1.概要说明 督查督办系统信息化平台适用于政府,企事业单位的重点项目跟进,重点工程部署,及各级精神的传达等督查督办性工作。开发设计坚持流程式管理的总体思路,充分体现督查事项立项的规...

孟娟
13分钟前
0
0
阿里靠什么支撑 EB 级计算力?

作者 关涛 阿里云智能事业群 研究员 导读:MaxCompute 是阿里EB级计算平台,经过十年磨砺,它成为阿里巴巴集团数据中台的计算核心和阿里云大数据的基础服务。去年MaxCompute 做了哪些工作,这...

zhaowei121
15分钟前
0
0
mybatis生成代码配置详解

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.o......

事儿爹
17分钟前
0
0
Vuex和表单绑定的一个神级坑再填一遍

vuex有一个很大的缺陷,就是和input输入框的v-model本身是冲突的。 官方文档给出了两种解决方案:https://vuex.vuejs.org/zh/guide/forms.html 一个是使用get和set → 适用于input框比较少的...

LinearLaw
20分钟前
0
0
CPU与GPU的区别

作者讲述的清楚: 我的理解:1 GPU ALU更多 2 Core 更多 3 业务更加专一(主要进行密集计算) 4 缓存区更少 https://www.zhihu.com/question/19903344...

南桥北木
20分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部