Java多線程ForkJoinPool實例詳解
引言
java 7提供了另外一個很有用的線程池框架,Fork/Join框架
理論
Fork/Join框架主要有以下兩個類組成.
* ForkJoinPool 這個類實現了ExecutorService接口和工作竊取算法(Work-Stealing Algorithm).它管理工作者線程,并提供任務的狀態(tài)信息,以及任務的執(zhí)行信息
* ForkJoinTask 這個類是一個將在ForkJoinPool執(zhí)行的任務的基類.
Fork/Join框架提供了在一個任務里執(zhí)行fork()和join()操作的機制和控制任務狀態(tài)的方法.通常,為了實現Fork/Join任務,需要實現一個以下兩個類之一的子類
* RecursiveAction 用于任務沒有返回值的場景
* RecursiveTask 用于任務有返回值的場景.
例子 先定個小目標,1億就太多,先賺個一百萬吧
現在你是一個深圳片區(qū)的某公司高級銷售主管.現在定了一個目標,就是要賺個一百,讓你一個人去賺,肯定有難度的.好在有一般手下,把目標縮小,讓小弟們去賺,我們坐等拿錢.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個手下去做,每個手下有繼續(xù)往下分,最終在七十幾號人的努力下,終于完成了目標–一百萬.而且還超出八十多萬,老板一開心,直接把八十多萬分給這七十多個員工分紅了.
后記
通過上面這個例子的學習,相信應該很多人都可以掌握ForkJoinPool這個類,它的核心就是要完成某一個目標任務,如果目標任務太大,那么就創(chuàng)建多個子任務.然后一直等待這些子任務完成.最終完成之前定下的目標任務.
總結
以上就是本文關于Java多線程ForkJoinPool實例詳解的全部內容,希望對大家有所幫助。歡迎各位參閱本站其他專題,有什么問題可以隨時留言,小編會及時回復大家的。
相關文章
Java 中 Date 與 Calendar 之間的編輯與轉換實例詳解
這篇文章主要介紹了Java 中 Date 與 Calendar 之間的編輯與轉換 ,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-07-07
springboot異步處理@NotBlank或@NotNull注釋校驗不生效問題
這篇文章主要介紹了springboot異步處理@NotBlank或@NotNull注釋校驗不生效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
Mybatis的@select和@SelectProvider注解方式動態(tài)SQL語句解讀
這篇文章主要介紹了Mybatis的@select和@SelectProvider注解方式動態(tài)SQL語句,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12

