ReentrantReadWriteLock(读写锁)

概念

ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。
读写锁比互斥锁允许对于共享数据更大程度的并发。每次只能有一个写线程,但是同时可以有多个线程并发地读数据。ReadWriteLock适用于读多写少的并发情况。

特性

1)支持公平和非公平的获取锁的方式;
2)支持可重入。读线程在获取了读锁后还可以获取读锁;写线程在获取了写锁之后既可以再次获取写锁又可以获取读锁;
3)还允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不允许的;
4)读取锁和写入锁都支持锁获取期间的中断;
5)Condition支持。仅写入锁提供了一个 Conditon 实现;读取锁不支持 Conditon ,readLock().newCondition() 会抛出 UnsupportedOperationException。

代码示例

示例一:利用重入来执行升级缓存后的锁降级

class CachedData {
  Object data;
  volatile boolean cacheValid;    //缓存是否有效
  ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

  void processCachedData() {
    rwl.readLock().lock();    //获取读锁
    //如果缓存无效,更新cache;否则直接使用data
    if (!cacheValid) {
      // Must release read lock before acquiring write lock
      //获取写锁前须释放读锁
      rwl.readLock().unlock();
      rwl.writeLock().lock();
      // Recheck state because another thread might have acquired
      //   write lock and changed state before we did.
      if (!cacheValid) {
        data = ...
               cacheValid = true;
      }
      // Downgrade by acquiring read lock before releasing write lock
      //锁降级,在释放写锁前获取读锁
      rwl.readLock().lock();
      rwl.writeLock().unlock(); // Unlock write, still hold read
    }

    use(data);
    rwl.readLock().unlock();    //释放读锁
  }
}

示例二:取代synchronize提交并发性能

class RWDictionary {
  private final Map<String, Data> m = new TreeMap<String, Data>();
  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  private final Lock r = rwl.readLock();    //读锁
  private final Lock w = rwl.writeLock();    //写锁

  public Data get(String key) {
    r.lock();
    try {
      return m.get(key);
    } finally {
      r.unlock();
    }
  }
  public String[] allKeys() {
    r.lock();
    try {
      return m.keySet().toArray();
    } finally {
      r.unlock();
    }
  }
  public Data put(String key, Data value) {
    w.lock();
    try {
      return m.put(key, value);
    } finally {
      w.unlock();
    }
  }
  public void clear() {
    w.lock();
    try {
      m.clear();
    } finally {
      w.unlock();
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值