引言
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