Java中静态代码块的线程安全性

46

假设我有一些Java代码:

public class SomeClass {
    static {
        private final double PI = 3.14;
        private final double SOME_CONSTANT = 5.76;
        private final double SOME_OTHER_CONSTANT = 756.33;
    }

  //rest of class
}
如果一个线程正在初始化 SomeClass 的 Class 对象,并且正在初始化静态块中的值,当第二个线程想要再次加载 SomeClass 的 Class 时,静态块会发生什么?第二个线程会忽略它并假设已经初始化,即使第一个线程没有完成吗?还是会发生其他事情?
5个回答

56
如果第一个线程还没有完成 SomeClass 的初始化,第二个线程将会被阻塞。
这在 Java 语言规范的 12.4.2 节 中有详细说明。

所以,它会被初始化两次,但不是并行的。 - user454322
10
不,它只会被初始化一次。第二个线程将等待第一个线程完成初始化后才继续 - 在此时它不会再次进行初始化。 - Jon Skeet
2
由于 _4。如果类或接口已经被初始化,则不需要采取进一步的操作.._? - user454322
4
是的,与第二步配合使用(阻塞直到线程被通知类已经初始化,然后重复执行)。 - Jon Skeet

17

Java保证静态类初始化是线程安全的。


2

0
由于Java编程语言是多线程的,因此类或接口的初始化需要仔细同步,因为可能有其他线程正在尝试同时初始化相同的类或接口。
引用自Java语言规范

0

静态块在初始化时始终是线程安全的。这就是使用单例对象的静态变量作为创建单例对象(单例设计模式)的一种方式的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接