读写锁ReentrantReadWriteLock性质

本文深入探讨了ReentrantReadWriteLock的特性,包括支持锁的降级但不支持升级,以及写锁支持newCondition而读锁不支持。通过具体代码示例,展示了在读多写少场景下,如何利用读写锁提升程序并发性,适用于系统缓存更新等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读写锁ReentrantReadWriteLock性质

一、性质

1、支持锁的降级,在写锁释放前降级为读锁
2、不支持锁的升级,由读锁升级为写锁将会失败
3、写锁支持ReentrantLock.newCondition,读锁不支持,将会抛出异常UnsupportedOperationException

锁的降级测试代码

        System.out.println("Enter");
        r.lock();
        System.out.println("read lock ");
        r.unlock();
        w.lock();
        System.out.println("write lock");
        r.lock();
        System.out.println("read lock");
        w.unlock();
        r.unlock();
        System.out.println("Outer");

        /*output:
            Enter
            read lock 
            write lock
            read lock
            Outer
        */

锁的升级测试代码

        System.out.println("Enter");
        r.lock();
        System.out.println("read lock ");
        w.lock();//将会一直阻塞
        System.out.println("write lock");
        w.unlock();
        r.unlock();
        System.out.println("Outer");

        /*output:
            Enter
            read lock 
            程序一直阻塞
        */

二、使用场景

在读多写少的场景下,使用读写锁提高程序的并发性 (实例代码来源于jdk源码注释))

1、提供一个读写目录,在读数据时获取读锁,写数据时获取写锁。只有读线程访问时,可以同时支持多个读线程访问,以此提供程序的并发性。

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(); }
   }
 }

2、系统缓存的更新,演示了锁的升级和降级使用

 class CachedData {
   Object data;
   volatile boolean cacheValid;
   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

   void processCachedData() {
     rwl.readLock().lock();
     if (!cacheValid) {
       // Must release read lock before acquiring write lock
       rwl.readLock().unlock();
       rwl.writeLock().lock();
       try {
         // 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();
       } finally {
         rwl.writeLock().unlock(); // Unlock write, still hold read
       }
     }

     try {
       use(data);
     } finally {
       rwl.readLock().unlock();
     }
   }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值