(十九)java多線程之ForkJoinPool

本人郵箱: <kco1989@qq.com>
歡迎轉載,轉載請註明網址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經所有託管github有須要的同窗自行下載java

引言

java 7提供了另一個頗有用的線程池框架,Fork/Join框架git

理論

Fork/Join框架主要有如下兩個類組成.github

  • ForkJoinPool 這個類實現了ExecutorService接口和工做竊取算法(Work-Stealing Algorithm).它管理工做者線程,並提供任務的狀態信息,以及任務的執行信息算法

  • ForkJoinTask 這個類是一個將在ForkJoinPool執行的任務的基類.編程

Fork/Join框架提供了在一個任務裏執行fork()join()操做的機制和控制任務狀態的方法.一般,爲了實現Fork/Join任務,須要實現一個如下兩個類之一的子類微信

  • RecursiveAction 用於任務沒有返回值的場景框架

  • RecursiveTask 用於任務有返回值的場景.dom

例子 先定個小目標,1億就太多,先賺個一百萬吧

如今你是一個深圳片區的某公司高級銷售主管.如今定了一個目標,就是要賺個一百,讓你一我的去賺,確定有難度的.好在有通常手下,把目標縮小,讓小弟們去賺,咱們坐等拿錢.ok,開始編程ide

  • 首先咱們要定義個賺錢任務 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這個類,它的核心就是要完成某一個目標任務,若是目標任務太大,那麼就建立多個子任務.而後一直等待這些子任務完成.最終完成以前定下的目標任務.

打賞

若是以爲個人文章寫的還過得去的話,有錢就捧個錢場,沒錢給我捧我的場(幫我點贊或推薦一下)
微信打賞
支付寶打賞

相關文章
相關標籤/搜索