java - 比 while (reentrantLock.isLocked()) 等待更好的解决方案

标签 java concurrency locking

我有一个提供对 map 的访问的服务 bean。有时我需要重建 map 的内容,这需要几秒钟的时间,并且我想在重建时阻止对 map 的访问,因为可以从不同的线程访问它。

@Service
public class MyService {
  private Map<Key,Value> cache = null;
  private ReentrantLock reentrantLock = new ReentrantLock();

   public void rebuildCache(){
     try {
       reentrantLock.lock();
       cache = new ConcurrentHashMap<>();
       ... //processing time consuming stuff and building up the cache
       }finally {
        reentrantLock.unlock();
     }
   }
    
   public Value getValue(Key key){
     while (lock.isLocked()){}
     return cache.get(key);
   }
   ...
}

如你所见,我使用

while (reentrantLock.isLocked()){}

检查锁是否已锁定并等待其解锁。这个解决方案似乎很脏。有更好的解决办法吗?

最佳答案

改用ReentrantReadWriteLock

在您的写入方法中:

theLock.writeLock().lock();
try {
    // update the map
} finally {
    theLock.writeLock().unlock();

  }

在 read 方法中,使用 .readLock() 代替。

但是这有一个问题,在 map 更新期间,所有读者都会被屏蔽;另一种解决方案是使用普通锁将旧映射的引用替换为新的、更新的映射,并使用普通的旧同步

<小时/>

更重要的是,您对锁的使用是不正确的。你应该这样做:

theLock.lock();
try {
    // whatever
} finally {
    theLock.unlock();
}

想象一下,如果当前锁定的锁定失败会发生什么:您将始终尝试解锁,最终会遇到 IllegalLockStateException

关于java - 比 while (reentrantLock.isLocked()) 等待更好的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32843259/

相关文章:

java - 无法删除路径

java - Java 小程序中的 drawImage 在 Safari 中闪烁

java.text.ParseException : Unparseable date (German, 乌克兰语)

java - 如何使用 JProgressBar

python - 将 Matplotlib 与 Django 结合使用

haskell - withMVar和bracket_的行为不同

java - Spring Security - 身份验证的用户名在 AuthenticationSuccessHandler 中为空

mysql - 如何正确使用事务和锁来保证数据库的完整性?

mysql - 如何解决MySQL中的锁定问题?

locking - 查询 SQL Server 存储过程中的关键部分