【问题标题】:ConcurrentHashMap needed with ReadWriteLock?ReadWriteLock 需要 ConcurrentHashMap 吗?
【发布时间】:2019-08-02 19:49:23
【问题描述】:

我有一个Map,它被多个线程读取,但(不时)被另一个线程清除和重建。

我已经用

包围了所有进入这张地图的通道
readWriteLock.readLock().lock()
try {
  ... access myMap here...
} finally {
  readWriteLock.readLock().unlock()
}

... 或 writeLock() 等效项,具体取决于访问类型。

我的问题是...ReadWriteLock 是否会确保对myMap 的更新对其他线程可见(因为它们必须等到unlock() 被写入线程调用之后?或者,我是否也需要将myMap 做成一个并发映射,比如ConcurrentHashMap

为了安全起见,我可能会这样做,但我想更好地理解。

【问题讨论】:

  • “重建”是什么意思?
  • @michalk 一个 map.clear() 后面跟着一堆 map.put() 电话。
  • ConcurrentHashMap 通常比 HashMap 快,即使在非并发使用时 - 通常更喜欢 ConcurrentHashMap
  • @BoristheSpider 但是我的try 块中的所有内容都保证“发生在”unlock() 之前吗?而且,如果是这样,我的理解是正确的,这意味着即使不使用ConcurrentHashMap,读者也会看到所有更新?
  • @BoristheSpider 这是一个非常有趣的声明,即即使在顺序代码中,ConcurrentHashMap 也比常规的更快。你有证据吗?

标签: java concurrency java.util.concurrent


【解决方案1】:

是的,即使没有线程感知映射也应该没问题。 Javadoc for ReadWriteLock 明确表示:

所有 ReadWriteLock 实现必须保证 writeLock 操作的内存同步效果(在 Lock 接口中指定)相对于关联的 readLock 也成立。也就是说,成功获取读锁的线程将看到在之前释放写锁时所做的所有更新。

(当然,通过使用读取器/写入器锁,您完全依赖于支持来自不同线程的并发查找的映射。可以想象巧妙的数据结构,它试图通过改变一些整体来节省时间查找期间的内部缓存状态。但标准集合(例如 HashMap)不会这样做)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2014-11-17
    • 2017-08-24
    • 2015-05-09
    • 2021-06-08
    • 2013-02-03
    相关资源
    最近更新 更多