ReadWriteLock - 读写锁

2021/01/05 posted in  并发工具

针对读多写少,JDK提供了ReadWriteLock,容易使用且性能较好;读写锁允许多个线程读共享变量,只允许一个线程写共享变量,如果一个线程写共享变量时,禁止读线程读共享变量

实现实例 -- 按需加载的缓存实现


class Cache<K,V> {
  final Map<K, V> m = new HashMap<>();
  final ReadWriteLock rwl =  new ReentrantReadWriteLock();
  final Lock r = rwl.readLock();
  final Lock w = rwl.writeLock();
 
  V get(K key) {
    V v = null;
    //读缓存
    r.lock();         ①
    try {
      v = m.get(key); ②
    } finally{
      r.unlock();     ③
    }
    //缓存中存在,返回
    if(v != null) {   ④
      return v;
    }  
    //缓存中不存在,查询数据库
    w.lock();         ⑤
    try {
      //再次验证
      //其他线程可能已经查询过数据库
      v = m.get(key); ⑥
      if(v == null){  ⑦
        //查询数据库
        v=省略代码无数
        m.put(key, v);
      }
    } finally{
      w.unlock();
    }
    return v; 
  }
}

原理实现

读写状态的设计

读写锁需要在同步状态上维护多个读线程和一个写线程

读写状态的确认:如果当前同步状态值为S,S不等于0当写状态等于0,读状态不等于0时,获取读锁

写锁的获取与释放

写锁是一个支持重进入的排他锁,如果当前线程已经获取写锁,增加写状态。如果当前线程在获取,如果当前线程在获取写锁时,读锁已经被获取,或者该线程不是已经获取写锁的线程,则当前线程进入等待状态

读锁的获取与释放

读锁是一个支持重进入的共享锁,它能够被多个线程同时获取;在没有其他线程访问时,读锁会被成功的获取,增加读状态,如果当前线程已经获取锁,则增加读状态,如果当前线程在获取读锁时,写锁已经被其他线程获取,则进入等待状态