调用
foo = new Foo();涉及到一些 *** 作,除非您引入适当的同步措施以防止同步,否则这些 *** 作可能会重新排序:
- 为新对象分配内存
- 写入字段的默认值(
a = 0
) - 写入字段的初始值(
a = 1
) - 发布对新创建对象的引用
没有适当的同步,步骤3和步骤4可能会重新排序(请注意,步骤2必须在步骤4之前发生),尽管x86架构上的热点不太可能发生。
为防止这种情况,您有几种解决方案,例如:
- 进入
a
决赛 - 同步访问
foo
(使用同步的init
AND getter)。
无需深入了解JLS#17,您可以阅读有关类初始化(强调我的意思)的JLS#12.4.1:
初始化代码不受限制的事实允许构建示例,在 该 示例中
,在评估其初始化表达式之前,当类变量的值仍具有其初始默认值时,就可以观察到该变量的值 ,但实际上这种示例很少见。(
这些示例也可以用于实例变量初始化
。)Java编程语言的全部功能在这些初始化程序中可用。程序员必须格外小心。这种功能给代码生成器带来了额外的负担,但是由于Java编程语言是并发的,因此无论如何都会出现这种负担。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)