【问题标题】:What is the exact meaning of final-field-safe context in JLSJLS中最终字段安全上下文的确切含义是什么
【发布时间】:2014-09-09 08:12:35
【问题描述】:

术语 final-field-safe context 在 JLS 的第 17.5.3 段(最终字段的后续修改)中经常使用。虽然,从规范中可以理解(如果我在这里错了,请纠正我)

An implementation may provide a way to execute a block of code
in a final-fieldsafe context.

确切的行为取决于实现,仍然没有明确的术语定义。
我可以假设,如果我们有一个 final-field freeze F (在对象构造结束时发生或通过反射 API 设置的 final-field)和一个动作 A ,这样 happens-before(F, A),那么 A 就在 final-field-safe 上下文中? p>

【问题讨论】:

    标签: java final jls


    【解决方案1】:

    为了帮助理解 JLS 17.5.3 的“最终字段安全上下文”的含义,请考虑以下代码

    public static final AccountType SINGLETON_ACCOUNT_TYPE = new AwesomeAccountType();
    

    在 Java 5 之前,Java 有一个“特性”,即构建 AwesomeAccountType 的线程安全性及其对 SINGLETON_ACCOUNT_TYPE 的分配被开发人员认为是安全的。不幸的是,规范是模棱两可的和/或没有说明行为,这导致不同的 JVM 实现具有不同的行为。结果是 Java 在这种情况下通常不是线程安全和可移植的。

    这样做的原因是,构建 AwesomeAccountType 所涉及的操作的顺序可能会在运行时重新排序,这样在对象完全构建之前,对对象的引用可能对另一个线程可见。这种行为是不确定的,它总是在单核 CPU 上工作,通常在英特尔 CPU 上工作,但在内存模型较弱的 CPU(如 Dec Alpha)上会很快崩溃。

    “最终字段安全上下文”是分配给上述最终字段 (SINGLETON_ACCOUNT_TYPE) 所涉及的代码区域,它涵盖了 AwesomeAccountType 的所有构造函数和 JVM 内部用于分配的代码并为对象初始化内存。

    Java 内存模型的这些更改是在 JSR133 下进行的,以下常见问题解答对于了解所做更改的上下文非常有用:JSR133 FAQ

    【讨论】:

    • 所以,我的猜测全错了。但我仍然感到困惑。在您发布的 JSR133 FAQ 的链接中,他们提到了“正确构造的对象”。当指向该对象的指针和指向它的最终字段的指针在构造过程中都没有泄漏时,我是否可以推测该对象是在最终字段安全的上下文中构造的?还是我又错了?
    • 几乎,“正确构造的对象”是指对象的引用在对象完全构造之前转义到其他代码的问题(或有发生这种情况的风险)。谷歌“在 Java 上双重检查锁定的问题”。 Doug Lea 撰写了一些深入研究这些问题的优秀文章,并为 JSR 133 奠定了基础。
    • cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 就是这样一个例子。关于该主题的维基百科页面也值得一读。 en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
    • 正确构造和正确发布对构造对象的引用是相关主题。是的,final 字段可以用作此发布的一部分(Java 5 之后)。但是,这不是唯一的方法,它本身也不能保证。例如,调用可能在对象上覆盖的方法的构造函数,然后调用另一个对象,不得将存储在“this”中的引用传递出对象,否则它可能正在发布尚未完全构造的对象.
    猜你喜欢
    • 2016-06-02
    • 2010-10-22
    • 2011-08-22
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 2011-05-06
    相关资源
    最近更新 更多