• java多线程-ReadWriteLock


    大纲:

    1. ReadWriteLock接口
    2. ReentrantReadWriteLock
    3. ReentrantReadWriteLock使用

    一、ReadWriteLock

    public interface ReadWriteLock {
        Lock readLock();
        Lock writeLock();
    }
    1. readLock获得读锁。
    2. writeLock获得写锁。

    二、ReentrantReadWriteLock是ReadWriteLock的实现类

    1. ReentrantReadWriteLock内部维护了两个实现Lock接口的内部类ReadLock读锁,与WriteLock写锁。
    2. 仅写锁支持condition。
    3. 锁降级:写锁降级为读锁,获取写锁、获取读锁、释放写锁。
    4. 锁升级:不支持读锁升级为写锁。
    5. 线程间互斥关系:读读共享锁、读写独享锁、写写独享锁
      public class Met {
          ReadWriteLock lock = new ReentrantReadWriteLock();
          public void read(Thread thread){
              try {
                  lock.readLock().lock();
                  System.out.println(thread.getName()+"read lock");
                  for(int i =0;i<10;i++){
                      System.out.println(thread.getName()+":"+i);
                  }
              } finally {
                  System.out.println(Thread.currentThread().getName()+"read unlock");
                  lock.readLock().unlock();
              }
          }
      
          public void write(Thread thread){
              try {
                  lock.writeLock().lock();
                  System.out.println(thread.getName()+"write lock");
                  for(int i =0;i<10;i++){
                      System.out.println(thread.getName()+":"+i);
                  }
              } finally {
                  System.out.println(Thread.currentThread().getName()+"write unlock");
                  lock.writeLock().unlock();
              }
          }
      }
      public class ReadRunnable implements Runnable {
          Met met;
          ReadRunnable(Met met){
              this.met = met;
          }
          @Override
          public void run() {
              met.read(Thread.currentThread());
          }
      }
      public class WriteRunnable implements Runnable {
          Met met;
          WriteRunnable(Met met){
              this.met = met;
          }
          @Override
          public void run() {
              met.write(Thread.currentThread());
          }
      }
      class TestReadWrite {
          public static void main(String[] args) {
              Met met = new Met();
              ReadRunnable read = new ReadRunnable(met);
              WriteRunnable write = new WriteRunnable(met);
              Thread threadread0 = new Thread(read);
              Thread threadread1 = new Thread(read);
              Thread threadwrite0 = new Thread(write);
              threadread0.start();
              threadread1.start();
              threadwrite0.start();
          }
      }

    三、ReentrantReadWriteLock使用

      官方demo:更新缓存后的锁降级,保持读锁。

    public class CachedData {
        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        String data = "未更新"; //缓存数据
        volatile boolean isValid; //缓存数据是否有效
        void processCachedData(){
            readWriteLock.readLock().lock();
            System.out.println(Thread.currentThread().getName()+"readLock.lock");
            //校验缓存数据是否有效,若无效跟新data,有效直接使用
            if(!isValid){
                System.out.println(Thread.currentThread().getName()+"readLock.unlock");
                readWriteLock.readLock().unlock();
                readWriteLock.writeLock().lock();
                System.out.println(Thread.currentThread().getName()+"writeLock.lock");
                //再次校验
                if(!isValid){
                    data = "已更新";
                    isValid = true;
                    System.out.println(Thread.currentThread().getName()+">>>refresh data");
                }
                //写锁降级为读锁:释放写锁前获取读锁
                readWriteLock.readLock().lock();
                System.out.println(Thread.currentThread().getName()+"readLock.lock");
                System.out.println(Thread.currentThread().getName()+"writeLock.unlock");
                //写锁被释放,读锁依旧
                readWriteLock.writeLock().unlock();
            }
            System.out.println(Thread.currentThread().getName()+">>>use data "+data);
            System.out.println(Thread.currentThread().getName()+"readLock.unlock");
            readWriteLock.readLock().unlock();
        }
    }
    public class ReadWriteRunnable implements Runnable {
        CachedData task;
        public ReadWriteRunnable(CachedData task){
            this.task = task;
        }
        @Override
        public void run() {
            task.processCachedData();
        }
    }
    class TestReadWrite {
        public static void main(String[] args) {
            CachedData task = new CachedData();
            ReadWriteRunnable readWriteRunnable = new ReadWriteRunnable(task);
            new Thread(readWriteRunnable).start();
            new Thread(readWriteRunnable).start();
            new Thread(readWriteRunnable).start();
            new Thread(readWriteRunnable).start();
            new Thread(readWriteRunnable).start();
            new Thread(readWriteRunnable).start();
        }
    }
  • 相关阅读:
    shiro的授权与认证
    spring-aop
    GC选择之串行收集与并行收集
    4. Tomcat调优
    spring boot 启动 开启注解 加载 bean
    一、JavaScript实现AJAX(只需四步)
    DVWA安装
    CTF入门指南
    Metasploit 学习
    JSP笔记
  • 原文地址:https://www.cnblogs.com/liuboyuan/p/10316411.html
Copyright © 2020-2023  润新知