语言规范中的Java静态初始化线程安全保证

aig*_*guy 2 java multithreading

人们普遍认为静态初始化是线程安全的.保证只发生一次.然而,我很好奇它在语言规范中确切地说会出现可见性问题吗?这来自http://www.ibm.com/developerworks/library/j-jtp03304/

此过程保证当一个线程在由给定监视器保护的同步块期间写入变量并在由同一监视器保护的同步块期间由另一个线程读取时,读取线程将可以看到该变量的写入.在没有同步的情况下,JMM不提供此保证

我从其他一些来源读过类似的东西.在静态初始化的情况下,我们不使用任何同步.假设初始化资源实际上是不可变的,并且我们从不写入它,那么就不会有用于访问它的同步,也不会使它变得不稳定.那么保证来自哪里读取线程不会看到空指针或部分初始化对象?显然,由于它在加载过程中发生,因此另一个线程不可能在之前读取该值并看到过时值,但是什么保证初始化结果不会停留在执行线程的本地内存中?我很好奇地阅读静态初始化是安全的原因.

编辑:我理解静态初始化是线程安全的.问题是为什么以及什么保证.

Jon*_*eet 7

我认为这实际上是JLS 12.4.2中类初始化规则的结果.这涉及在锁上同步,仅在执行静态初始化器和字段初始化器之后释放它.锁定获取和释放然后影响线程模型的"发生之前"部分,通过JLS 17.4.4(我认为 - 我不是这方面的专家).

请注意,12.4.2说明:

实现可以通过在步骤1中消除锁获取(并且在步骤4/5中释放)来优化该过程,此时它可以确定类的初始化已经完成,只要在存储器模型方面,所有发生 -在获取锁之前存在的排序之前,在执行优化时仍然存在.