静态初始化threadlocking中的Lambdas

时间:2017-12-28 22:41:10

标签: java multithreading lambda java-8

使用并行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;
    }
}

有没有人知道为什么第一个代码块线程锁定而第二个代码块没有?

1 个答案:

答案 0 :(得分:4)

当类static初始化时,JVM保持类级锁。锁可以防止其他线程在完全初始化之前访问该类。

无论如何,没有必要做你想做的事。 new Object[9]数组已初始化为所有空值。更不用说,即使它确实有效,并行性也有很多开销。开销将远远超过将此任务分配到多个核心的任何好处。 (有9个元素没有任何好处。)