Lock写入HashMap

时间:2014-08-01 11:18:09

标签: java multithreading concurrency

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

是否有一种锁定地图的方法,以便只能发生阻塞所有写入线程的读取,因此在解锁映射后,所有修改都会发生?锁需要能够在我使用ConcurrentHashMap的同时允许多个线程写入,并且我想利用ConcurrentHashMap的好处。

3 个答案:

答案 0 :(得分:4)

ConcurrentHashMap不提供方法调用之间的线程安全性,仅在单个调用中提供。因此,如果要在执行操作时保持映射不变,则需要使用自己的锁将调用包装到地图中。

例如,使用ReadWriteLock:

ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

更新地图时

readWriteLock.writeLock().lock();

// do the updates

readWriteLock.writeLock().unlock();

当你想要从地图上阅读时

readWriteLock.readLock().lock();

// perform the read and its operations that rely on the map not changing

readWriteLock.readLock().unlock();

答案 1 :(得分:3)

为什么不使用受ConcurrentHashMap保护的ReentrantReadWriteLock但向后使用?

myLock.writeLock().lock();
try {
    return myMap.get(...);
} finally {
    myLock.writeLock().unlock();
}

myLock.readLock().lock();
try {
    myMap.put(..., ...);
} finally {
    myLock.readLock().unlock();
}

这非常难看,需要在评论中进行覆盖,以便警告一位不知情的后续开发人员,当你持readLock时正在写作,并在持writeLock时阅读但我不知道看看为什么它不起作用。

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

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

答案 2 :(得分:0)

如何将HashMap包装到一个放置某种

的类中
boolean isLocked

假设你想从一个线程开始阅读过程,你可以检查这个锁

if(!myClass.getLockState())
{ //perform whatever you want to do }

如果确保所有线程都使用相同的myClass对象,这可能是锁定/解锁hashMap的简单解决方案。