引言
java 7提供了另外一個很有用的線程池框架,Fork/Join框架
理論
Fork/Join框架主要有以下兩個類組成.
* ForkJoinPool 這個類實現了ExecutorService接口和工作竊取算法(Work-Stealing Algorithm).它管理工作者線程,并提供任務的狀態信息,以及任務的執行信息
* ForkJoinTask 這個類是一個將在ForkJoinPool執行的任務的基類.
Fork/Join框架提供了在一個任務里執行fork()和join()操作的機制和控制任務狀態的方法.通常,為了實現Fork/Join任務,需要實現一個以下兩個類之一的子類
* RecursiveAction 用于任務沒有返回值的場景
* RecursiveTask 用于任務有返回值的場景.
例子 先定個小目標,1億就太多,先賺個一百萬吧
現在你是一個深圳片區的某公司高級銷售主管.現在定了一個目標,就是要賺個一百,讓你一個人去賺,肯定有難度的.好在有一般手下,把目標縮小,讓小弟們去賺,我們坐等拿錢.ok,開始編程
首先我們要定義個賺錢任務 MakeMoneyTask,如果要賺錢的目標小于最小目標,比如十萬,那么就自己去完成,否則,就把任務分給小弟們去做.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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; } } |
最后我們寫一個測試類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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()); } } |
運作之后結果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
員工 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這個類,它的核心就是要完成某一個目標任務,如果目標任務太大,那么就創建多個子任務.然后一直等待這些子任務完成.最終完成之前定下的目標任務.
總結
以上就是本文關于Java多線程ForkJoinPool實例詳解的全部內容,希望對大家有所幫助。歡迎各位參閱本站其他專題,有什么問題可以隨時留言,小編會及時回復大家的。
原文鏈接:http://blog.csdn.net/tianshi_kco/article/details/53026192#comments