摘要
JDK:1.8.0_202
# 一:前言
先看下面两个代码块,他们运行中都是会有问题的。
# 1.1 代码1
public class Client1 {
private static List<String> list = new ArrayList<>();
static {
System.out.println("================start================");
list.addAll(IntStream.range(0, 3).mapToObj(e -> String.format("第 %s 位", e)).collect(Collectors.toList()));
System.out.println("=====================================");
list.addAll(IntStream.range(3, 6).parallel().mapToObj(e -> String.format("第 %s 位", e)).collect(Collectors.toList()));
System.out.println("================end================");
}
public static void main(String[] args) {
print();
}
private static void print() {
list.forEach(System.out::println);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
运行结果
# 1.2 代码2
public class Client2 {
private static List<String> list = new ArrayList<>();
static {
System.out.println("================run================");
System.out.println("static:" + Thread.currentThread().getName());
List<String> temp = IntStream.range(0, 10).mapToObj(String::valueOf).collect(Collectors.toList());
System.out.println("====================================");
System.out.println("static:" + Thread.currentThread().getName());
list.addAll(temp.parallelStream().map(e -> String.format("第 %s 位", e)).collect(Collectors.toList()));
System.out.println("================end================");
}
public static void main(String[] args) {
System.out.println("main:" + Thread.currentThread().getName());
print();
}
private static void print() {
list.forEach(System.out::println);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
运行结果
# 1.3 有何问题
可以发现项目运行到 parallel 相关的代码的时候,就会 "卡住",同时如果看堆栈信息,就会发现有报错。
# 二:问题原因
下面以上面代码中,第二个例子结果进行说明,先看结果打印的最上层堆栈信息
如果觉得不够详细,可以查看下面更加详细的堆栈信息
"ForkJoinPool.commonPool-worker-1" #20 daemon prio=5 os_prio=0 tid=0x000000001f815000 nid=0x17260 in Object.wait() [0x000000002096e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-6" #17 daemon prio=5 os_prio=0 tid=0x000000001f81c000 nid=0x18798 in Object.wait() [0x000000002086e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-8" #19 daemon prio=5 os_prio=0 tid=0x000000001f819800 nid=0x16adc in Object.wait() [0x000000002076e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-15" #18 daemon prio=5 os_prio=0 tid=0x000000001f816800 nid=0x17138 in Object.wait() [0x000000002066e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-13" #16 daemon prio=5 os_prio=0 tid=0x000000001f814800 nid=0x14e68 in Object.wait() [0x000000002046e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-4" #15 daemon prio=5 os_prio=0 tid=0x000000001f808800 nid=0x15570 in Object.wait() [0x000000002036e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-11" #14 daemon prio=5 os_prio=0 tid=0x000000001f7fc000 nid=0x1704 in Object.wait() [0x000000002026e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-2" #13 daemon prio=5 os_prio=0 tid=0x000000001f7f6000 nid=0x17a28 in Object.wait() [0x000000002016e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"ForkJoinPool.commonPool-worker-9" #12 daemon prio=5 os_prio=0 tid=0x000000001f7f5800 nid=0xd10c in Object.wait() [0x000000002006e000]
java.lang.Thread.State: RUNNABLE
at com.ccjjltx.temp.Client2$$Lambda$6/1607521710.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:747)
at java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:721)
at java.util.stream.AbstractTask.compute(AbstractTask.java:316)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"main" #1 prio=5 os_prio=0 tid=0x0000000000d3e800 nid=0x13374 in Object.wait() [0x0000000002a9e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076f3028e0> (a java.util.stream.ReduceOps$ReduceTask)
at java.util.concurrent.ForkJoinTask.externalAwaitDone(ForkJoinTask.java:334)
- locked <0x000000076f3028e0> (a java.util.stream.ReduceOps$ReduceTask)
at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:405)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.ccjjltx.temp.Client2.<clinit>(Client2.java:18)
"ForkJoinPool.commonPool-worker-10" #21 daemon prio=5 os_prio=0 tid=0x000000001f81a800 nid=0x1616c waiting on condition [0x0000000020a6f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076f302740> (a java.util.concurrent.ForkJoinPool)
at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001db86800 nid=0x11dc0 runnable [0x000000001f16e000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x000000076ee78960> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x000000076ee78960> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:49)
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001c3e3000 nid=0x183c4 in Object.wait() [0x000000001ee6f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ed08ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x000000076ed08ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000001dad3000 nid=0x11430 in Object.wait() [0x000000001ed6f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ed06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076ed06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001dc45800 nid=0x17848 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001db95000 nid=0x17628 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001db93000 nid=0x14380 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001db92800 nid=0x15de0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001db89000 nid=0x17bbc waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001dae8000 nid=0x160cc waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001db4a800 nid=0x1954 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"VM Thread" os_prio=2 tid=0x000000001c3d5800 nid=0x13430 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002d18800 nid=0x18848 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002d1a000 nid=0x14cf0 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002d1b800 nid=0x15228 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002d1d000 nid=0xb954 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002d20800 nid=0x148dc runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002d21800 nid=0xca10 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002d24800 nid=0x13220 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002d26000 nid=0x14f30 runnable
"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x0000000002d27000 nid=0xd5b0 runnable
"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x0000000002d28000 nid=0x151b8 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001dc73000 nid=0x177c0 waiting on condition
JNI global references: 328
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
可以发现 ForkJoinPool.commonPool-worke-* 的线程是 RUNNABLE,这个状态并不一定是正在执行,也可能是准备好了,等待执行。
1. main线程等待ForkJoinPool.commonPool-worker-*线程
ForkJoinPool.commonPool-worker-*执行完,外部类的静态代码块才能执行完,main线程才能往下走
2. ForkJoinPool.commonPool-worker-*线程等待main线程
因为ForkJoinPool要执行lamda,说白了就是这个类的一个内部类,这个类正在有main线程完成初始化。
这样就是两个线程互相等待,造成死锁了
对于这个问题,之前就有人给jdk官方提过bug: https://bugs.openjdk.java.net/browse/JDK-8143380 (opens new window) 但是jdk官方认为这个不是bug,是使用的人自己的问题,就关闭了这个问题
同理,下面这种写法一样不可行:
private static final Map<String, String> STRUCT_MAP = Arrays.asList("a", "b", "c").
parallelStream().filter(e -> e != null).collect(Collectors.toMap(e -> e, e -> e, (o1, o2) -> o1));
1
2
2
# 三:解决方法
方法一:
静态代码块不使用并发流(parallel()),使用普通的流就好了
方法二:
分一个子线程执行 static
public class Client3 {
private static List<String> list = new ArrayList<>();
static {
new Thread(() -> {
System.out.println("================run================");
System.out.println("static:" + Thread.currentThread().getName());
List<String> temp = IntStream.range(0, 10).mapToObj(String::valueOf).collect(Collectors.toList());
System.out.println("====================================");
System.out.println("static:" + Thread.currentThread().getName());
list.addAll(temp.parallelStream().map(e -> String.format("第 %s 位", e)).collect(Collectors.toList()));
System.out.println("================end================");
}).start();
}
public static void main(String[] args) {
System.out.println("main:" + Thread.currentThread().getName());
print();
}
private static void print() {
list.forEach(System.out::println);
}
}
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
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
运行结果: