JUC——ReadWriteLock读写锁

1:ReadWriteLock读写锁介绍

ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,提升系统性能。用锁分离的机制来提升性能非常容易理解,比如线程A1、 A2. A3进行写操作,B1、B2、B3进行读操作,如果使用重入锁或者内部锁,从理论上说所有读之间、读与写之间、写和写之间都是串行操作。当B1进行读取时,B2、 B3 则需要等待锁。由于读操作并不对数据的完整性造成破坏,这种等待显然是不合理的。因此,读写锁就有了发挥功能的余地。

在这种情况下,读写锁允许多个线程同时读,使得B1、B2、B3之间真正并行。但是,考虑到数据完整性,写写操作和读写操作间依然是需要相互等待和持有锁的。总的来说,读写锁的访问约束情况如下

  • 读-读不互斥: 读读之间不阻塞。

  • 读-写互斥: 读阻塞写,写也会阻塞读。

  • 写-写互斥:写写阻塞
    果在系统中,读操作的次数远远大于写操作的次数,则读写锁就可以发挥最大的功效,提升系统的性能

2:ReadWriteLock读写锁演示

我们来模拟在缓存(MyCache)中进行读,写分离操作演示
不使用ReadWriteLock的情况演示

class MyCache{
  private volatile HashMap<String,String> hashMap= new HashMap();
  public  void put(String key,String value) throws InterruptedException {
      System.out.println(Thread.currentThread().getName()+"----写入数据");
      TimeUnit.MICROSECONDS.sleep(300);
      hashMap.put(key,value);
      System.out.println(Thread.currentThread().getName()+"----写入数据完成");
  }
    public  void get(String key) throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"读取数据");
        TimeUnit.MICROSECONDS.sleep(300);
        hashMap.get(key);
        System.out.println(Thread.currentThread().getName()+"读取数据完成");
    }
}
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.put(inttempt+" ",inttempt+"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.get(inttempt+" ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

在这里插入图片描述
使用ReadWriteLock的情况演示

class MyCache{
  private volatile HashMap<String,String> hashMap= new HashMap();
3  private ReadWriteLock readWriteLock= new ReentrantReadWriteLock();
  public  void put(String key,String value) throws InterruptedException {
5      readWriteLock.writeLock().lock();
      try{
          System.out.println(Thread.currentThread().getName()+"----写入数据");
          TimeUnit.MICROSECONDS.sleep(300);
          hashMap.put(key,value);
          System.out.println(Thread.currentThread().getName()+"----写入数据完成");
      }catch(Exception e){
         e.printStackTrace();
      }finally{
          readWriteLock.writeLock().unlock();
      }
  }
    public  void get(String key) throws InterruptedException {
16      readWriteLock.readLock().lock();
      try{
          System.out.println(Thread.currentThread().getName()+"读取数据");
          TimeUnit.MICROSECONDS.sleep(300);
          hashMap.get(key);
          System.out.println(Thread.currentThread().getName()+"读取数据完成");
      }catch(Exception e){
         e.printStackTrace();
      }finally{
          readWriteLock.readLock().unlock();
      }
    }
}
public class ReadWriteLockDemo {
    public static void main(String[] args) {

        MyCache myCache = new MyCache();

        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.put(inttempt+" ",inttempt+"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
        for (int i=0;i<5;i++){
            final  int inttempt=1;
            new Thread(()->{
                try {
                    myCache.get(inttempt+" ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

在这里插入图片描述

读线程完全并行,而写会阻塞读。如果使用读写锁这段程序2秒就可以结束,如果使用可重入锁和内部锁,整个程序执行时间将要到5秒左右

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值