【问题标题】:Is ConcurrentHashMap analogy to CopyOnWriteArrayListConcurrentHashMap 是否类似于 CopyOnWriteArrayList
【发布时间】:2013-04-03 07:58:51
【问题描述】:

我经常使用CopyOnWriteArrayList。当

  • 线程执行大量读取
  • 线程执行少量写入

不过,我会在什么时候使用Collections.synchronizedList()

  • 线程执行少量读取
  • 线程执行大量写入

这是因为根据CopyOnWriteArrayList Java Doc

ArrayList 的线程安全变体,其中所有可变操作 (添加、设置等)是通过制作新的副本来实现的 底层数组。

这通常太昂贵了,...

当谈到ConcurrentHashMap 时,我想知道在选择ConcurrentHashMap 而不是Collections.synchronizedMap() 时我是否仍然可以应用相同的逻辑?

ConcurrentHashMap 是否会在我每次执行写操作时重新创建底层数据结构的副本?如果写操作多于读操作,它的性能会比 Collections.synchronizedMap 差吗?

【问题讨论】:

标签: java


【解决方案1】:

不,ConcurrentHashMap 不会制作底层数据结构的新副本。

ConcurrentHashMap 是一个分段映射,分段数基于并发级别。当你写入一个段时,它会被锁定直到写入完成。

【讨论】:

    【解决方案2】:

    ConcurrentHashMap 几乎总是适合使用,因为它比同类产品具有更好的性能和更有用的 API(您可以避免 check-then-set 线程问题)
    它使用锁剥离进行更细粒度的访问,并且不复制地图。
    唯一您不应该使用ConcurrentHashMap的应用程序是您需要锁定地图以实现独占访问权

    【讨论】:

    • 是的。我知道。但这还没有解决我的问题。每次执行写操作时,ConcurrentHashMap 是否都会对底层数据结构进行新的复制?
    • 首先,如果性能被记录为比同类产品最好,您为什么要关心它的作用?不,它不复制。它使用锁剥离来修改底层地图的部分
    • 因为当写操作多于读操作时,CopyOnWriteArrayList 的性能比其对应的 Collections.synchronizedList 差。因此,我关心这种行为是否也发生在 ConcurrentHashMap 中。
    • CopyOnWriteArrayList 是当你做的主要访问是遍历列表时的最佳选择。否则它不是最佳选择。此外,BlochGoetz 推荐 ConcurrentHashMap 性能最佳。
    • 我会使用同步集合,因为您通常希望只有一个线程在使用它,但您需要线程安全以防万一。我会使用并发集合,您有时会在线程之间发生争用。
    【解决方案3】:

    当写入ConcurrentHashMap时。它只在内部锁定正在写入的映射部分。因此通过这种行为,我们可以很容易地看到它不会生成新副本,而是在同一个副本中进行更改。
    因此,当我们尝试写入 ConcurrentHashMap 时,这意味着我们正在尝试写入任何段,然后它只会锁定该段并仅更新该段。所以简单来说,它永远不会制作任何新的副本。所以你的问题的答案是NO。

    【讨论】:

      【解决方案4】:

      我发现的主要区别是 ConcurrentHashMap 中的自定义“并发级别”。 我们可以询问 JVM 需要多少块(段)来划分 Map。将创建许多锁。 CopyOnWriteArrayList 使用简单的创建克隆并更新它的简单过程。 (这后来被 JVM 与原始数组列表合并。)

      【讨论】:

        猜你喜欢
        • 2011-06-19
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2011-11-29
        • 1970-01-01
        • 1970-01-01
        • 2015-05-15
        • 2010-12-21
        相关资源
        最近更新 更多