锁定写入 HashMap

use*_*702 3 java concurrency multithreading

我有一个正在异步更新的 HashMap。我需要执行涉及地图的操作,这些操作要求地图在任务期间不改变状态,例如根据地图的内容对值进行排序。

有没有一种方法可以锁定映射,以便只能进行读取,从而阻塞所有写入线程,因此在映射解锁后,所有修改都可以发生?当我使用 ConcurrentHashMap 时,锁需要能够允许多个线程同时写入,并且我想利用 ConcurrentHashMap 的优势。

Ric*_*ich 6

为什么不使用受 aConcurrentHashMap保护的 aReentrantReadWriteLock而是向后使用它?

myLock.writeLock().lock();
try {
    return myMap.get(...);
} finally {
    myLock.writeLock().unlock();
}
Run Code Online (Sandbox Code Playgroud)

myLock.readLock().lock();
try {
    myMap.put(..., ...);
} finally {
    myLock.readLock().unlock();
}
Run Code Online (Sandbox Code Playgroud)

这非常丑陋,需要在注释中覆盖,以警告不熟悉的后续开发人员,您实际上是在按住 时编写readLock并在按住 时阅读,writeLock但我不明白为什么它不起作用。

为了清楚起见,您甚至可以编写自己的代码来InversedReentrantReadWriteLock包装实数ReentrantReadWriteLock以反转调用并使代码更具可读性。

如果,正如 @GPI 建议的那样,您想要处于读取模式或写入模式,但保留该模式下的并发性,则可以使用AtomicIntegerAtomicLong实现锁。正值可以表示处于读取模式,负值表示处于写入模式。为零表示锁可以进入任一模式。这立即变得更加复杂,因为您必须自己实现锁,而上面概述的并发写入与独占读取解决方案仅依赖于现有的 API 类。(我确信如果您愿意,我可以解决一个问题,但我无法立即提供答案)

  • 我不确定......它很丑陋,但它似乎能达到我想要的效果。 (2认同)