首页 > 解决方案 > 如何在 put() 期间阻止 ConcurrentHashMap get() 操作

问题描述

ConcurrentHashMap<String, Config> configStore = new ConcurrentHashMap<>();
...
void updateStore() {
  Config newConfig = generateNewConfig();
  Config oldConfig = configStore.get(configName);
  if (newConfig.replaces(oldConfig)) {
   configStore.put(configName, newConfig);
  }
}

可以由多个线程读取,ConcurrentHashMap但只能由单个线程更新。我想在操作正在进行get()时阻止操作。put()这里的基本原理是,如果一个put()操作正在进行,这意味着映射中的当前条目是陈旧的,并且所有get()操作都应该阻塞,直到put()完成。在不同步整个地图的情况下,如何在 Java 中实现这一点?

标签: javamultithreadingconcurrencyhashmapsynchronization

解决方案


看起来你可以推迟这个compute,它会为你解决这个问题:

Config newConfig = generateNewConfig();
configStore.compute(
    newConfig,
    (oldConfig, value) -> {
       if (newConfig.replaces(oldConfig)) {
            return key;
       }
       return oldConfig;
    }
);

使用此方法可以获得两个保证:

在计算过程中,其他线程对该映射的一些尝试更新操作可能会被阻塞,因此计算应该简短而简单

整个方法调用以原子方式执行

根据其文档。


推荐阅读