JUC - 读写锁:

读写锁:

在这里插入图片描述

  1. 读写锁的基本讲解与使用

    • ReadWriteLock同Lock一样也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个是只读的锁,一个是写锁。 读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的(排他的)。 每次只能有一个写线程,但是可以有多个线程并发地读数据。所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。理论上,读写锁比互斥锁允许对于共享数据更大程度的并发。与互斥锁相比,读写锁是否能够提高性能取决于读写数据的频率、读取和写入操作的持续时间、以及读线程和写线程之间的竞争
    • 适用的场景:
      • 程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁
    • 互斥的原则:
      • 读-读能共存,多个读者可以同时进行读
      • 读-写不能共存,写者必须互斥(只允许一个写者写,也不能读者、写者同时进行)
      • 写-写不能共存 写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
  2. 读写锁的基本使用:

    • 继承关系:
      在这里插入图片描述
    • 构造方法:
      在这里插入图片描述
      从构造方法可以看出默认的创建一个非公平锁 要是在构造方法中传入的是一个true表示的是创建一个公平锁
    • 代码演示:
      class MyCache{
          private  volatile  Map<String,String> map = new HashMap<>();
          private  ReadWriteLock rwLock = new ReentrantReadWriteLock();
          public  void put(String key,String value){
              rwLock.writeLock().lock();
              try {
                  System.out.println(Thread.currentThread().getName()
                          +"\t 准备写入数据"+key);
                      TimeUnit.MILLISECONDS.sleep(200);
                  map.put(key, value);
                  System.out.println(Thread.currentThread().getName()
                          +"\t 写入数据完成"+key);
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  rwLock.writeLock().unlock();
              }
          }
          public  void get(String key){
              rwLock.readLock().lock();
              try {
                  System.out.println(Thread.currentThread().getName()
                          +"\t 准备读取数据"+key);
      
                      TimeUnit.MILLISECONDS.sleep(200);
      
                  String value = map.get(key);
                  System.out.println(Thread.currentThread().getName()
                          +"\t 读取数据完成"+value);
      
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  rwLock.readLock().unlock();
              }
          }
      }
      
      public class ReadWriteLockDemo {
      
          public static void main(String[] args) throws InterruptedException {
      
              MyCache myCache = new MyCache();
      
              for (int i = 1; i <=5 ; i++) {
                  String key = String.valueOf(i);
                  new Thread(()->{
                      myCache.put(key,UUID.randomUUID().toString().substring(0,8));
                  },String.valueOf(i)).start();
              }
      
              TimeUnit.SECONDS.sleep(2);
      
              for (int i = 1; i <=5 ; i++) {
                  String key = String.valueOf(i);
                  new Thread(()->{
                      myCache.get(key);
                  },String.valueOf(i)).start();
              }
          }
      }
      
  3. 具体方法的使用:

    • 创建读写锁 ReadWriteLock readWriteLock = new ReentrantReadWriteLock();可使用两种锁,写锁和读锁

    • 加写锁 readWriteLock.writeLock().lock();

    • 解写锁

      finally {
           readWriteLock.writeLock().unlock();
       }
      
    • 加读锁 readWriteLock.readLock().lock();

    • 解读锁

      finally {
          readWriteLock.readLock().unlock();
      }
      

版权声明:本文为qq_41922608原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。