我在使用并行 lambda 时遇到了以下问题。
我在一个类中有一个静态初始化 block ,它并行地迭代数组,但是,我从堆栈跟踪中注意到,第一次迭代正确完成并且计算机,但是所有后续迭代都会阻塞。 (线程转储状态为“等待:”)这确实没有帮助。
这是线程锁定的代码。
public static class Test {
private static final Object[] objects;
static {
objects = new Object[9];
IntStream.range(0, objects.length).parallel().forEach(i -> objects[i] = null);
}
}
在苦思冥想为什么将数组索引设置为 null 会导致线程锁定之后,我得出了以下结论。 我在静态 block 中创建了一个临时数组,然后在最后分配了类数组,这解决了问题。
public static class Test {
private static final Object[] objects;
static {
Object[] tempObjects = new Object[9];
IntStream.range(0, tempObjects.length).parallel().forEach(i -> tempObjects[i] = null);
objects = tempObjects;
}
}
有谁知道为什么第一个代码块线程锁定而第二个代码块没有?
最佳答案
当类被静态初始化时,JVM 会持有类级锁。在类完全初始化之前,锁会阻止其他线程访问该类。
无论如何,没有必要做你想做的事情。 new Object[9]
数组已初始化为所有空值。更不用说,即使它确实有效,并行性也会产生大量的开销。开销将远远超过将此任务分散到多个核心所带来的任何好处。 (9 个元素没有任何好处。)
关于java - 静态初始化程序线程锁定中的 Lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48015274/