【问题标题】:Is "ConcurrentHashMap.putAll(...)" atomic?“ConcurrentHashMap.putAll(...)”是原子的吗?
【发布时间】:2011-12-14 23:35:02
【问题描述】:

方法 ConcurrentHashMap.putAll(Map) 应该是原子的吗?

我在文档中找不到它,ConcurrentMap 接口中也没有提到它,所以我猜答案是否定的。我要求它确定,因为说实话,如果该操作不是原子的,那就没有意义了。

如果它不是原子的,那么支持多个项目的原子插入的最佳方式是什么?回到过去的好同步?

【问题讨论】:

    标签: java atomic concurrenthashmap


    【解决方案1】:

    它不是原子的,不。根据the class documentation

    对于putAllclear 等聚合操作,并发检索可能仅反映插入或删除某些条目。

    要原子化它,你必须使用synchronized,是的。没有非阻塞方式可以做到这一点。

    【讨论】:

    • 另一个(非标准)并发 Map 实现呢?
    • @pst 哪个可能是候选人?
    • @JaperD。我不知道。只是想知道您是否有任何见解,尽管没有这个答案仍然是完整的。
    • @pst:这是个好问题。在不知道确切的用例的情况下,但总的来说,我猜这会适得其反。 ConcurrentHashMap 是你可能称之为“概率并发”的东西:它不是完全非阻塞的,但它通过在内部拆分为固定数量的段(默认为 16,但可在构造函数中设置)来工作,希望当多个不同的线程同时写入地图,它们将可能写入不同段中的条目。如果它们确实写入同一段,则可能会出现一定程度的阻塞。 (续)
    • (续)要使putAll 成为原子的,您必须完全摆脱它(因为您不能原子地报告多个段已更新)。也就是说,这取决于您的业务分布。如果您期望正常的puts 相对较少,但期望有很多gets 和putAlls,那么创建一个使用ReadWriteLock 来控制的HashMap 的子类可能是有意义的访问:所有读取都将被包裹在一个读锁中,所有写入,包括整个putAll,都将被包裹在一个写锁中。
    【解决方案2】:

    the doc的顶部

    对于putAllclear等聚合操作,并发 检索可能仅反映某些条目的插入或删除。

    【讨论】:

      【解决方案3】:

      putAll() 不是原子的,只是保证每个 put() 都是原子的。

      【讨论】:

        【解决方案4】:

        要原子化它,你必须使用同步,是的

        不仅如此:您必须在每个公共 map 方法周围放置一个同步块,从而降低并发性。

        【讨论】:

          猜你喜欢
          • 2011-03-03
          • 2010-12-11
          • 2020-05-07
          • 2013-01-26
          • 2019-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多