我们知道新的JMM可以保证不会看到部分构造的对象或其最终字段的多个值。 http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.2
我的问题是 -
当我们反序列化不可变对象(声明为final的所有字段)时,最终保证是否适用?
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
(UPDATE)
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6379948(反序列化的错误)
当我们克隆一个不可变对象(声明为final的所有字段)时,最终保证是否适用?
答案 0 :(得分:0)
如果使用线程安全集合或容器将对象传递给另一个线程,您将看到该类的正确状态。这意味着内置队列,同步集合,锁定集合,原子引用或易失性。
即使看到这样的问题,你也必须使用一个本身不能是线程安全的访问,因为你使用的任何写/读屏障都会确保正确的初始化。
答案 1 :(得分:0)
反序列化对象时,唯一可以获得对它的引用的方法是在反序列化完成后返回它。此时,已分配了其字段。
通常,获取对未完全初始化对象的引用的唯一方法是它的超类构造函数是否将对this
的引用传递给另一个线程。
如果关注的是未标记为volatile
的反序列化对象的可变字段的值可能位于一个CPU上的处理器缓存中而未刷新到主内存,我实际上无法用权限回答但如果保证与运行构造函数的保证不同,我会非常惊讶。