我有一个定义如下的 CHM。每当有任何更新时,我都会从单个后台线程调用 setDataProcess
方法。我总是从多个阅读器线程调用 getDataMapping
。
private static final ConcurrentHashMap<ProcessType, Mapping> mappingsHolder = new ConcurrentHashMap<ProcessType, Mapping>();
private static final CountDownLatch hasInitialized = new CountDownLatch(ProcessType.values().length);
public static void setDataProcess(ProcessType processType, Mapping newMapData) {
mappingsHolder.put(processType, newMapData);
hasInitialized.countDown();
}
public static Mapping getDataMapping(ProcessType processType) {
try {
hasInitialized.await();
return mappingsHolder.get(processType);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
}
问题是 - mappingsHolder
CHM 中的任何更改都会立即对所有阅读器线程可见,或者我需要为此使用 volatile 吗?
最佳答案
据我所知,您在读取方法中使用了 CountDownLatch
来等待计数达到零。计数显然是 ProcessType
中枚举常量的数量。如果此 CountDownLatch
得到正确实现,应该不会有问题,因为根据 javadocs , 应该有一个 happens-before 关系:
Memory consistency effects: Until the count reaches zero, actions in a thread prior to calling
countDown()
happen-before actions following a successful return from a correspondingawait()
in another thread.
忽略 CountDownLatch
因素,ConcurrentHashMap
不同步检索键,但检索与键对应的最新值。
Retrieval operations (including
get
) generally do not block, so may overlap with update operations (includingput
andremove
). Retrievals reflect the results of the most recently completed update operations holding upon their onset.
这意味着线程所做的更改对于读取 key 的线程是可见的。但两者会相互干扰。
关于java - ConcurrentHashMap 更改对所有线程可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31212168/