【问题标题】:I'm trying to increment value for ConcurrentHashMap我正在尝试增加 ConcurrentHashMap 的值
【发布时间】:2019-04-11 14:26:55
【问题描述】:

全部采用多线程编程,没有 Guava。 我的问题与this one 相同,但我想在没有break; 的情况下解决它。我已经阅读了这个主题,但仍然没有解决问题,我在多线程中出生,所以也许解决方案在这里,但我看不到它。

我正在数单词。如果这个词已经满足,则增加值,如果没有,只需将新节点放入映射中,键为wordvalue 1。

这是我的代码,它是错误的。我想避免任何循环。

String word = m.group();
if(wordMap.putIfAbsent(word, 1) == null){
    Integer old;
    while (!wordMap.replace(word, old = wordMap.get(word), old + 1));
}

【问题讨论】:

    标签: java multithreading thread-safety java.util.concurrent concurrenthashmap


    【解决方案1】:

    merge-Method 是您最有可能寻找的方法:

    String word = m.group();
    wordMap.merge(word, 1, Integer::sum);
    

    【讨论】:

      【解决方案2】:

      您之前引用的link中提供的解决方案,已经有了最优解决方案。

      您可以使用 Java 8 的 computeIfPresent() 和 putIfAbsent() 功能,因为它们确实处理并发。 ConcurrentMap 处理多线程环境中键/值操作的内存一致性。

      根据documentation,对给定键的更新操作与报告更新值的该键的任何(非空)检索具有发生前的关系。

      【讨论】:

      • 但是如果我同时使用computeIfPresent() 和putIfAbsent() 会导致过度验证。我想进行一项验证,然后根据其中一项说明继续此结果。
      • 在这种情况下,您可以使用 compute() 如下: wordMap.compute(word,(k,v) -> (v == null) ? 1 : v + 1);根据您的要求,如果您的单词在地图中没有出现,这将添加新条目,或者如果存在则增加值
      • 但是当你像 2 条没有同步的指令一样使用它(或者像这样)时,它会变成非原子的。
      • 是的,根据文档,在计算过程中,其他线程对特定地图的任何尝试更新操作都可能会被阻止。
      • 我不是说你错了,我的意思是,线程被阻塞直到计算完成,但这并不能使它完全非原子。我同意更简单的实现是实现@codeflush.dev 提供的解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多