【发布时间】:2018-01-29 15:57:35
【问题描述】:
JavaDoc for ConcurrentHashMap states:
检索操作(包括 get)一般不会阻塞,因此可能与更新操作(包括 put 和 remove)重叠。检索反映了最近完成的更新操作在其开始时保持的结果。 (更正式地说,给定键的更新操作与报告更新值的键的任何(非空)检索具有发生前的关系。)
由于“对给定键的更新操作...发生之前...对该键的任何(非空)检索”并且部分构造的对象被认为是非空的,*以下代码是否可能允许Thread2 访问部分构造的对象?
Thread1:
// Immutable Object (all fields final)
concurrentHashMap.put("immutableObject", new ImmutableObject());
// Volatile Object (all fields volatile)
concurrentHashMap.put("volatileObject", new VolatileObject());
// Thread-safe Mutable Object
concurrentHashMap.put("mutableObject", new MutableObject());
Thread2:
concurrentHashMap.get("immutableObject");
concurrentHashMap.get("volatileObject");
concurrentHashMap.get("mutableObject");
是否需要在这些对象的构造函数中执行某种同步,以确保在它们完全初始化之前没有线程访问它们?
* 我不能 100% 确定部分构造的对象被认为是非空的,但我没有看到任何相反的证据。似乎由于线程可以访问部分初始化的对象,部分初始化的对象不能为空,因为某些内部数据(无论是初始化的)是可访问的。
【问题讨论】:
-
没有。在对象完全构造之前,put 不会继续。
-
@AlexSalauyou 不确定如何回答“如何”,但有可能。例如cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
标签: java concurrency concurrenthashmap