使用并行lambda时遇到了以下问题。
我在一个类中有一个静态初始化块,它并行迭代一个数组,然而,我从堆栈跟踪中注意到第一次迭代正确地完成了计算机,但是所有后续迭代都阻塞了。 (线程转储状态“等待:”),这实际上没有用。
以下是线程锁定的代码。
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会导致线程锁定,我想出了以下内容。 我在静态块中创建了一个临时数组,然后在最后分配了类数组来修复问题。
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;
}
}
有没有人知道为什么第一个代码块线程锁定而第二个代码块没有?
答案 0 :(得分:4)
当类static
初始化时,JVM保持类级锁。锁可以防止其他线程在完全初始化之前访问该类。
无论如何,没有必要做你想做的事。 new Object[9]
数组已初始化为所有空值。更不用说,即使它确实有效,并行性也有很多开销。开销将远远超过将此任务分配到多个核心的任何好处。 (有9个元素没有任何好处。)