我遇到了一个奇怪的情况,在静态初始化程序中使用带有lambda的并行流看似永远没有CPU利用率.这是代码:
class Deadlock {
static {
IntStream.range(0, 10000).parallel().map(i -> i).count();
System.out.println("done");
}
public static void main(final String[] args) {}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是此行为的最小再现测试用例.如果我:
代码立即完成.谁能解释这种行为?这是一个错误还是这个意图?
我正在使用OpenJDK版本1.8.0_66-internal.
注意:这是不是重复,请仔细阅读题目сarefully /sf/users/241389361/报价:
真正的问题是为什么代码有时会起作用.即使没有lambdas,问题也会重现.这让我觉得可能存在JVM错误.
在/sf/answers/3759645221/的评论中,我试图找出原因,为什么代码的行为从一个开始到另一个不同,并且该讨论的参与者给了我一些建议来创建一个单独的主题.
不要考虑以下源代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
有时(几乎总是)它会导致死锁.
输出示例:
static initializer: main
map: main 2
map: ForkJoinPool.commonPool-worker-3 4
map: ForkJoinPool.commonPool-worker-3 3
map: ForkJoinPool.commonPool-worker-2 0
Run Code Online (Sandbox Code Playgroud)
但有时它会成功完成(非常罕见):
static initializer: main
map: main 2
map: main …Run Code Online (Sandbox Code Playgroud)