JLS第17.5.3段(最终字段的后续修改)中经常使用术语“最终字段安全”上下文。虽然,从规范中可以理解(如果我在这里错了,请纠正我)
An implementation may provide a way to execute a block of code
in a final-fieldsafe context.
确切的行为取决于实现,因此尚无明确的术语定义。
我是否可以假设,如果我们有一个最终字段卡住F(在对象构造或通过反射API设置的最终字段结束时卡住)和一个 Action A,这样的情况发生在before(F,A ),那么A在最终字段安全的环境中吗?
最佳答案
为了帮助理解JLS 17.5.3对“最终字段安全上下文”的含义,请考虑以下代码
public static final AccountType SINGLETON_ACCOUNT_TYPE = new AwesomeAccountType();
在Java 5之前,Java具有一个“功能”,开发人员认为AwesomeAccountType的构造及其分配给SINGLETON_ACCOUNT_TYPE的线程安全性是安全的。不幸的是,规范是模棱两可的和/或没有说明行为,这导致不同的JVM实现具有不同的行为。结果是在这种情况下Java通常不是线程安全和可移植的。
这样做的原因是,在构造AwesomeAccountType时所涉及的操作顺序可以在运行时重新排序,以使得在完全构造对象之前,对该对象的引用对于另一个线程可以变得可见。该行为是不确定的,它始终在单核CPU上运行,并且通常在intel CPU上运行,但是在内存模型较弱的CPU(例如Dec Alpha)上急于解决。
然后,“最终字段安全上下文”是分配给上述最终字段(SINGLETON_ACCOUNT_TYPE)所涉及的代码区域,它涵盖了AwesomeAccountType的所有构造函数以及JVM内部用于分配和初始化内存的代码。对象的内存。
对Java内存模型的这些更改是在JSR133下进行的,以下常见问题解答对于理解所做更改的上下文非常有用:JSR133 FAQ。