ReadWriteLock
如果是内部锁、可重入锁,在进行读操作、写操作时,是串行执行的
由于读操作不会对数据产生变更,所以这段串行等待时间可以优化。(读的耗时越多,读写锁的优势更明显)
- 所以在“读-读”、或者“读大于写”的情况下加普通的锁就会影响性能
- 读写锁用的是同一个 Sycn 同步器,因此等待队列、state 等也是同一个。因此读跟写是互斥的
使用注意事项
- 读锁不支持条件变量
重入时升级不支持:即持有读锁的情况下去获取写锁,会导致获取写锁永久等待
class CachedData {Object data;// 是否有效,如果失效,需要重新计算 datavolatile boolean cacheValid;final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();void processCachedData() {rwl.readLock().lock();if (!cacheValid) {// 获取写锁前必须释放读锁rwl.readLock().unlock();rwl.writeLock().lock();try {// 判断是否有其它线程已经获取了写锁、更新了缓存, 避免重复更新if (!cacheValid) {data = ...cacheValid = true;}// 降级为读锁, 释放写锁, 这样能够让其它线程读取缓存rwl.readLock().lock();} finally {rwl.writeLock().unlock();}}rw1.readLock().unlock();}}
注意释放写锁是在获取读锁之后,反过来则不行
