多线程开发B - ReadWriteLock 读写锁

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


多线程开发B - ReadWriteLock 读写锁

ReadWriteLock将读锁和写锁相分离,在没有写的场景下,读读是不阻塞,无等待的,
最高级别的并发,注意的是在涉及写的时候,读和写都需要申请锁,因此写的过程中,可能会读到旧数据,导致数据不一致。

ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。
Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。

代码示例:

  /**
       * 读锁
       * @throws InterruptedException
       * */
      public static void read() throws InterruptedException {
            try {
                  lock.readLock().lock();
                  long startTime = System.currentTimeMillis();
                  System.out.println("【read】 start !!!");
                  for (int i = 0; i < 4; i++) {
                        Thread.sleep(20);
                        System.out.printf("【%s】读取数据中...\n",Thread.currentThread().getName());
                  }
                  System.out.println("【read】 end 耗时"+((System.currentTimeMillis()-startTime))+"毫秒");
            }finally {
                  System.out.println("--------读取结束---------"); 
                  lock.readLock().unlock();
            }
      }
      /**
       * 读锁 - 写锁
       * @throws InterruptedException
       * */
      public static void readAndWrite() throws InterruptedException {
            try {
                  lock.readLock().lock();
                  long startTime = System.currentTimeMillis();
                  System.out.println("【read】 start !!!");
                  for (int i = 0; i < 4; i++) {
                        Thread.sleep(20);
                        System.out.printf("【%s】读取数据中...\n",Thread.currentThread().getName());
                  }
                  write();
                  System.out.println("【read】 end 耗时"+((System.currentTimeMillis()-startTime))+"毫秒");
            }finally {
                  System.out.println("--------读取结束---------"); 
                  lock.readLock().unlock();
            }
      }
      /**
       * 写锁
       * @throws InterruptedException
       * */
      public static void write() throws InterruptedException {
            try {
                  lock.writeLock().lock();
                  long startTime = System.currentTimeMillis();
                  System.out.println("【write】 start !!!");
                  for (int i = 0; i < 4; i++) {
                        Thread.sleep(20);
                        System.out.printf("【%s】写入数据中...\n",Thread.currentThread().getName());
                  }
                  System.out.println("【write】 end 耗时"+((System.currentTimeMillis()-startTime))+"毫秒");
            }finally {
                  System.out.println("--------写入结束---------"); 
                  lock.writeLock().unlock();
            }
      }
      
      /**
       * 写锁 - 读锁 
       * @throws InterruptedException
       * */
      public static void writeAndRead() throws InterruptedException {
            try {
                  lock.writeLock().lock();
                  long startTime = System.currentTimeMillis();
                  System.out.println("【write】 start !!!");
                  read();
                  for (int i = 0; i < 4; i++) {
                        Thread.sleep(20);
                        System.out.printf("【%s】写入数据中...\n",Thread.currentThread().getName());
                  }
                  System.out.println("【write】 end 耗时"+((System.currentTimeMillis()-startTime))+"毫秒");
            }finally {
                  System.out.println("--------写入结束---------"); 
                  lock.writeLock().unlock();
            }
      }

1、读锁-读锁 效果:无阻塞 不获取锁

代码示例:

public static void main(String[] args) {
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);     
        //读锁 
        for (int i = 0; i < 4; i++) {
            newFixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                              try {
                                    read();
                              } catch (InterruptedException e) {
                                    e.printStackTrace();
                              }
                        }
                  });
            }
        newFixedThreadPool.shutdown();           
      }

效果:
在这里插入图片描述

说明:
读读是不阻塞,无等待的, 最高级别的并发,即读锁使用共享模式。


2、读锁-写锁 效果:阻塞 获取锁

代码示例:

public static void main(String[] args) {
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);     
      //读锁-写锁  效果:阻塞
        for (int i = 0; i < 4; i++) {
            newFixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                              try {                         
                                    readAndWrite();
                              } catch (InterruptedException e) {
                                    e.printStackTrace();
                              }
                        }
                  });
            }
      
        newFixedThreadPool.shutdown();           
 }

效果:
在这里插入图片描述

说明:
锁升级,ReentrantReadWriteLock是不支持的,即读锁不能升级到写锁,也可以说一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容,读写锁之间为互斥。


3、写锁-读锁 效果:不阻塞 获取锁

代码示例:

public static void main(String[] args) {
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);     
      //读锁-写锁  效果:阻塞
        for (int i = 0; i < 4; i++) {
            newFixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                              try {                         
                                    writeAndRead();
                              } catch (InterruptedException e) {
                                    e.printStackTrace();
                              }
                        }
                  });
            }
      
        newFixedThreadPool.shutdown();           
}

效果:
在这里插入图片描述

说明:
ReentrantReadWriteLock支持锁降级,即写锁可以降级到读锁。


4、写锁 效果:不阻塞、获取锁

代码示例:

public static void main(String[] args) {
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);     
      //读锁-写锁  效果:阻塞
        for (int i = 0; i < 4; i++) {
            newFixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                              try {                         
                                    write();
                              } catch (InterruptedException e) {
                                    e.printStackTrace();
                              }
                        }
                  });
            }
      
        newFixedThreadPool.shutdown();           
}

效果:
在这里插入图片描述

说明:
写锁是互斥的,独立的,即写写之间是互斥模式。


总结:

  1. 读读是不阻塞,无等待的, 最高级别的并发,即读锁使用共享模式。
  2. 锁升级,ReentrantReadWriteLock是不支持的,即读锁不能升级到写锁,也可以说一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容,读写锁之间为互斥。
  3. ReentrantReadWriteLock支持锁降级,即写锁可以降级到读锁。
  4. 写锁是互斥的,独立的,即写写之间是互斥模式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栗子~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值