ReentrantReadWriteLock

一、为什么使用

  多个线程 同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源应该可以同时进行,
  但是如果一个线程想去写共享资源,就不应该再有其它线程可以对该资源进行读或写

二、例子

             class MyCache{

              /**
               * 缓存中的东西,必须保持可见性,因此使用volatile修饰
               */
              private volatile Map<String, Object> map = new HashMap<>();


              /**
               * 创建一个读写锁
               * 它是一个读写融为一体的锁,在使用的时候,需要转换
               */
              private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

              /**
               * 定义写操作
               * 满足:原子 + 独占
               * @param key
               * @param value
               */
              public void put(String key, Object value){

                  // 创建一个写锁
                  rwLock.writeLock().lock();
                  try {
                      System.out.println(Thread.currentThread().getName() + "\t 正在写入:" + key);
                      Thread.sleep(1000);
                      map.put(key, value);
                      System.out.println(Thread.currentThread().getName() + "\t 写入完成");
                  } catch (Exception e) {
                      e.printStackTrace();
                  } finally {
                      // 写锁 释放
                      rwLock.writeLock().unlock();
                  }

              }

              /**
               * 获取
               * @param key
               */
              public void get(String key){
                  // 创建一个读锁
                  rwLock.readLock().lock();
                  try {
                      System.out.println(Thread.currentThread().getName() + "\t 正在读取:");
                      Object value = map.get(key);
                      System.out.println(Thread.currentThread().getName() + "\t 读取完成:" + value);
                  } catch (Exception e) {
                      e.printStackTrace();
                  } finally {
                      // 读锁 释放
                      rwLock.readLock().unlock();
                  }
              }

          }


        @Test
        void ReentrantReadWriteLockTest(){
            MyCache myCache = new MyCache();

            // 线程操作资源类,5个线程写
            for (int i = 1; i <= 5; i++) {
                // lambda表达式内部必须是final
                final int tempInt = i;
                new Thread(() -> {
                    myCache.put(tempInt + "", tempInt +  "");
                }, String.valueOf(i)).start();
            }

            // 线程操作资源类, 5个线程读
            for (int i = 1; i <= 5; i++) {
                // lambda表达式内部必须是final
                final int tempInt = i;
                new Thread(() -> {
                    myCache.get(tempInt + "");
                }, String.valueOf(i)).start();
            }
        }
posted @ 2021-11-04 20:16  jock_javaEE  阅读(24)  评论(0编辑  收藏  举报