问题描述
Goetz的,第41页,提及 c>是如何生效的呢?显然有一些巫术之后,但什么?
I don't quite get this. If the publication is the last statement in the constructor, hasn't all the constructing work been done before that? How come is this not valid by then? Apparently there's some voodoo going on after that, but what?
推荐答案
构造函数的结束是一个特殊的地方在并发,相对于最终字段。从Java语言规范的节:
The end of a constructor is a special place in terms of concurrency, with respect to final fields. From section 17.5 of the Java Language Specification:
最终字段的使用模型是一个简单的
。为
中的对象的
构造函数中的对象设置最终字段。不要在正在构造的对象中写入引用
,在
中,另一个线程可以在对象的构造函数
完成之前看到
。如果是这样,那么
当对象被另一个
线程看到时,该线程将总是看到
正确构造的版本的
对象的最后字段。它将
也看到由最终字段
引用的任何对象或
数组的版本,它们至少与
最后字段一样是最新的。
The usage model for final fields is a simple one. Set the final fields for an object in that object's constructor. Do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are.
换句话说,如果检查在另一个线程中的对象,你的监听器可能会看到final字段及其默认值。如果侦听器注册在构造函数完成后发生,则不会发生这种情况。
In other words, your listener could end up seeing final fields with their default values if it examines the object in another thread. This wouldn't happen if listener registration happened after the constructor has completed.
根据发生的情况,我怀疑在一个构造函数,确保所有线程看新的数据;没有应用内存屏障,可能会出现问题。
In terms of what's going on, I suspect there's an implicit memory barrier at the very end of a constructor, making sure that all threads "see" the new data; without that memory barrier having been applied, there could be problems.
这篇关于什么是“不完全构造的对象”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!