Java 将哈希映射锁定到其他线程

Java 将哈希映射锁定到其他线程,java,thread-safety,Java,Thread Safety,我有一个作为缓存的并发Hashmap。我很高兴多个线程同时从缓存中读取数据,但是如果缓存正在重新加载写入缓存,我不希望线程能够在重新加载缓存时读取缓存,而是从备份缓存中读取 我一直在研究reentractLock类,但是可以使用它来锁定缓存,我所看到的示例似乎只是锁定方法 一旦缓存被锁定,我希望其他线程从另一个缓存读取,是否有一种方法可以说明这一点: if (cache isLocked) { read from secondary cache } else { read from ca

我有一个作为缓存的并发Hashmap。我很高兴多个线程同时从缓存中读取数据,但是如果缓存正在重新加载写入缓存,我不希望线程能够在重新加载缓存时读取缓存,而是从备份缓存中读取

我一直在研究reentractLock类,但是可以使用它来锁定缓存,我所看到的示例似乎只是锁定方法

一旦缓存被锁定,我希望其他线程从另一个缓存读取,是否有一种方法可以说明这一点:

if (cache isLocked) 
{
 read from secondary cache  
}
else {
read from cache
}
提前谢谢你

ReentrantLock类包含一个isLocked方法,如果锁被线程持有,该方法将返回true。您可以使用它来检查线程是否应该使用常规缓存或备份缓存

if (reentrantLock.isLocked()) 
{
 //read from secondary cache  
}
else {
 //read from cache
}

因此,当您需要更新缓存时,重载线程将调用ReentrantLock对象的方法锁,使所有读取线程都使用备份缓存。更新完成后,重新加载线程将被称为unlock,使所有读取线程使用常规缓存。

ConcurrenthashMap in Internal synchronized,因此您不必担心这一点。只要你在使用它的新的原子变异方法,你就应该很好。什么样的用例会让你担心它不起作用呢?用例是:从数据库获取数据时需要重新加载缓存,还需要清除缓存。如果另一个线程在重新加载期间尝试读取缓存,则不会返回任何数据,这将导致业务逻辑出现问题,并导致用户接收错误消息。我假设这个问题是按照您的建议在内部处理的,但我的一位资深且经验丰富的同事坚持认为情况并非如此。它可以处理……它将由ConcurrenthashMap处理,但不是整个地图,而是地图的切片部分。请参阅ConcurrenthashMap使用锁协作,并在发生变异操作时锁定其底层存储的一部分。它在内部使用重入锁。因此,如果再次重新加载缓存,如果用户请求一个尚未重新加载的密钥,他将在填充地图时获得旧值,如果他请求一个新的旧值,他将获得一个新值。只要地图重新加载部分使用ConcurrenthashMap的原子突变方法,你就不需要为它锁定地图。如果你不想让用户在整个重新加载操作完成之前在地图上做任何事情,那么使用可重入的锁是正确的方法,尽管我个人认为这是一种过激的行为。谢谢Ortis。因此,要真正锁定地图,只需执行以下操作:myLock.lock;->重新加载缓存->完成->myLock.unlock的逻辑;