为什么在静态初始值设定项中使用并行流会导致不稳定的死锁
注意:这不是重复的,请阅读主题сare https://stackoverflow.com/users/3448419/apangin 引用:
真正的问题是为什么代码有时在不应该工作的时候工作。即使没有 lambda,问题也会重现。这让我觉得可能有一个JVM错误。
在 https://stackoverflow.com/a/53709217/2674303 的评论中,我试图找出为什么代码从一个开始到另一个开始的行为不同,讨论的参与者向我提出了一条建议,以创建一个单独的主题。
让我们考虑以下源代码:
public class Test {
static {
System.out.println("static initializer: " + Thread.currentThread().getName());
final long SUM = IntStream.range(0, 5)
.parallel()
.mapToObj(i -> {
System.out.println("map: " + Thread.currentThread().getName() + " " + i);
return i;
})
.sum();
}
public static void main(String[] args) {
System.out.println("Finished");
}
}
有时(几乎总是)它会导致死锁。
输出示例:
static initializer: main
map: main 2
map: ForkJoinPool.commonPool-worker-3 4
map: ForkJoinPool.commonPool-worker-3 3
map: ForkJoinPool.commonPool-worker-2 0
但有时它成功完成(非常罕见):
static initializer: main
map: main 2
map: main 3
map: ForkJoinPool.commonPool-worker-2 4
map: ForkJoinPool.commonPool-worker-1 1
map: ForkJoinPool.commonPool-worker-3 0
Finished
或
static initializer: main
map: main 2
map: ForkJoinPool.commonPool-worker-2 0
map: ForkJoinPool.commonPool-worker-1 1
map: ForkJoinPool.commonPool-worker-3 4
map: main 3
你能解释一下这种行为吗?