为什么这个静态最终变量在单例线程安全中?

MyT*_*tle 13 java multithreading

阅读本网站,我发现了这个:

[]行private static final Foo INSTANCE = new Foo();只在实际使用类时执行,它负责延迟实例化,并保证线程安全.

为什么这保证是线程安全的?因为这个领域是最终的?还是出于其他原因?

ysh*_*vit 25

因为它是最终的,是的.最终变量具有特殊的线程安全语义,因为其他线程保证至少在其构造函数完成时看到最终字段.

这是在JLS 17.5中,虽然语言有点密集.这些语义是在Java 1.5中引入的,特别是JSR-133.有关JSR-133及其各种含义的非规范讨论,请参阅此页面.

请注意,如果它的构造后修改的情况下,即没有一定线程安全的.在这种情况下,您必须采取通常的螺纹安全预防措施,以确保发生在边缘之前.

我相当肯定(虽然不是100%)只有一个线程进行类初始化的事实不是这里的一个因素.确实这个类只是由一个线程初始化,但是我不相信在该线程之间建立任何其他使用该类的线程的任何特定的发生前边缘(除了那个其他线程不需要重新初始化)班级).因此,如果没有final关键字,另一个线程将能够看到对象的部分构造的实例.JMM定义的特定发生前边缘在JLS 17.4.5中,并且那里没有列出类初始化.


ase*_*ovm 5

类构造函数和静态/实例初始化程序保证以原子方式执行,因为它们private static final FOO INSTANCE = new FOO;等效于

private static final FOO INSTANCE;

static{
    INSTANCE = new FOO();
}
Run Code Online (Sandbox Code Playgroud)

这种情况属于上述类别.