【问题标题】:Locking ConcurrentHashMap for an exclusive read锁定 ConcurrentHashMap 以进行独占读取
【发布时间】:2020-06-15 17:01:34
【问题描述】:

我有几个线程可以将信息保存到我的ConcurrentHashMap<K,V>。我应该在父线程中拍摄整个 Map 的快照,处理其中的信息并最终从所有值和键中清空它。

如何确保在读取过程中(在父线程中),在我完成之前不会被任何写入它的子线程更新?是否可以用信号量或互斥锁来锁定这个数据结构?

【问题讨论】:

  • 您可以简单地使用监视器和synchronize

标签: java multithreading concurrency locking concurrenthashmap


【解决方案1】:

试试这样的。使用监视器保护地图field,因此当您拍摄快照时,其他人无法将值放入其中。

public class Example<K, V> {
    private final Map<K, V> map = new HashMap<>();
    private final Object monitor = new Object();

    public Object snapshot() {
        synchronized (monitor) {
            // take the snapshot and return it
        }
    }

    public V put(K key, V value) {
        synchronized (monitor) {
            return map.put(key, value);
        }
    }
}

此外,在此示例中,您可以通过使用简单的 HashMap 而不是 ConcurrentHashMap 来简化它,因为您有监视器保护对该字段的访问。

【讨论】:

  • 那么使用 ConcurrentHashMap 的意义何在?
  • 没错,我只是使用它,因为问题作者正在使用它。但在这种情况下,您可以使用HashMap 来简化它。
  • 谢谢,效果很好。我使用 ConcurrentHashMap 因为我认为多个线程需要它来共享它并安全地保存数据。当我从中获取快照时,我想确保在处理数据时没有人可以访问它。
  • 如果地图返回的 entrySet 没有反映任何其他更新,但它确实像文档所说的 here 那样工作。
  • @chriptus13 这不是entrySet() 的特殊属性。不支持锁定整个地图是ConcurrentHashMap的通用属性。
【解决方案2】:

使用ReadWriteLock

这给了你一副锁:

  • 读锁,多线程可以同时获取
  • 写锁,只有一个线程可以持有,在持有期间没有线程可以持有读锁。

尽管有名字,但没有理由必须将这些锁用于专门的读写:

  • 获取(并释放)正在更新映射的线程的读锁
  • 为必须立即查看整个地图的线程获取(并释放)写锁。

【讨论】:

    猜你喜欢
    • 2013-07-27
    • 2012-01-30
    • 2020-10-17
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多