为什么单例线程安全的此静态最终变量安全? [英] Why is this static final variable in a singleton thread-safe?

查看:112
本文介绍了为什么单例线程安全的此静态最终变量安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读此网站时,我发现:

Reading this site, I've found this:

[The]行private static final Foo INSTANCE = new Foo();仅在实际使用该类时才执行,这将处理延迟实例化,并确保其是线程安全的.

[The] line private static final Foo INSTANCE = new Foo(); is only executed when the class is actually used, this takes care of the lazy instantiation, and is it guaranteed to be thread safe.

为什么这保证是线程安全的?因为此字段是最终?还是出于其他原因?

Why this guaranteed to be thread safe? Because this field is final? Or for some other reason?

推荐答案

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

Because it's final, yes. Final variables have special thread-safety semantics, in that other threads are guaranteed to see the final field in at least the state it was in when its constructor finished.

这在 JLS 17.5 ,尽管语言有点密集.这些语义是在Java 1.5中引入的,尤其是 JSR-133 .有关JSR-133及其各种含义的非规范讨论,请参见本页.

This is in JLS 17.5, though the language there is a bit dense. These semantics were introduced in Java 1.5, in particular by JSR-133. See this page for a non-spec discussion of JSR-133 and its various implications.

请注意,如果在实例的构造函数之后修改实例,则不是不一定是线程安全的.在这种情况下,您必须采取常规的线程安全预防措施以确保在边缘发生之前发生.

Note that if you modify the instance after its constructor, that is not necessarily thread safe. In that case, you have to take the usual thread safety precautions to ensure happens-before edges.

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

I'm fairly sure (though not quite 100%) that the fact that only one thread does the class initialization is not a factor here. It's true that the class is only initialized by one thread, but I don't believe there are any specific happens-before edges established between that thread any any other thread that uses the class (other than that other thread not having to re-initialize the class). So, without the final keyword, another thread would be able to see a partially-constructed instance of the object. The specific happens-before edges the JMM defines are in JLS 17.4.5, and class initialization is not listed there.

这篇关于为什么单例线程安全的此静态最终变量安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆