Java多线程——读写锁ReentrantReadWriteLock

概述

ReentrantReadWriteLock,是一种读写锁,对读写操作的多线程访问提供了特殊处理,可以提高读取操作的性能,让读并发,写加锁。

  • 读操作可并发
  • 读写操作互斥
  • 写操作互斥

其原理与ReentrantLock基本一直,只不过加入了读写锁的逻辑,底层也是使用了AQS同步器,AQS的源码解析可查阅我的另一篇文章:Java多线程——JUC之AQS(AbstractQueuedSynchronizer)分析,ReentrantLock的实现原理解析

基本使用

package com.leolee.multithreadProgramming.juc.reentrantReadWriteLock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @ClassName Test
 * @Description: reentrantReadWriteLock,读写锁,可以提高读取操作的性能,让读并发,写加锁
 * @Author LeoLee
 * @Date 2021/3/7
 * @Version V1.0
 **/
@Slf4j
public class Test {

    public static void main(String[] args) {
        Test.test2();
    }

    /*
     * 功能描述: 
* 〈验证读写锁——多线程【读】操作是否互斥〉 * 结果:读写锁的读操作是不互斥的 * @Param: [] * @Return: void * @Author: LeoLee * @Date: 2021/3/7 13:55 */ public static void test1() { ReadWriteLock readWriteLock = new ReadWriteLock(); new Thread(() -> { readWriteLock.read(); }, "t1").start(); new Thread(() -> { readWriteLock.read(); }, "t2").start(); } /* * 功能描述:
* 〈验证读写锁——多线程【读写】操作是否互斥〉 * 结果:读写锁的读写操作是互斥的 * @Param: [] * @Return: void * @Author: LeoLee * @Date: 2021/3/7 13:55 */ public static void test2() { ReadWriteLock readWriteLock = new ReadWriteLock(); new Thread(() -> { readWriteLock.read(); }, "t1").start(); new Thread(() -> { readWriteLock.write(); }, "t2").start(); } } @Slf4j class ReadWriteLock { private Object data; private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); //读锁 private ReentrantReadWriteLock.ReadLock readLock = rwl.readLock(); //写锁 private ReentrantReadWriteLock.WriteLock writeLock = rwl.writeLock(); public Object read() { log.info("获取读锁..."); readLock.lock(); try { log.info("读取操作"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } finally { log.info("释放读锁..."); readLock.unlock(); } return data; } public void write() { log.info("获取写锁..."); writeLock.lock(); try { log.info("写入操作"); } finally { log.info("释放写锁..."); writeLock.unlock(); } } }

注意事项:

  • 读锁不支持条件变量,也就是无法使用Condition
  • ReentrantReadWriteLock是可重入锁,但是不支持重入的锁升级,即有读锁的情况下去获取写锁,会导致获取写锁永久等待,发生死锁在持有写锁的情况下,是可以支持获取读锁的

Javadoc关于重入情况下,写锁降级为读锁的示例

* 
 {@code
 * class CachedData {
 *   Object data;
 *   volatile boolean cacheValid;
 *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 *
 *   void processCachedData() {
 *     rwl.readLock().lock();
 *     if (!cacheValid) {
 *       // Must release read lock before acquiring write lock
 *       rwl.readLock().unlock();
 *       rwl.writeLock().lock();
 *       try {
 *         // Recheck state because another thread might have
 *         // acquired write lock and changed state before we did.
 *         if (!cacheValid) {
 *           data = ...
 *           cacheValid = true;
 *         }
 *         // Downgrade by acquiring read lock before releasing write lock
 *         rwl.readLock().lock();
 *       } finally {
 *         rwl.writeLock().unlock(); // Unlock write, still hold read
 *       }
 *     }
 *
 *     try {
 *       use(data);
 *     } finally {
 *       rwl.readLock().unlock();
 *     }
 *   }
 * }}

 

 

你可能感兴趣的:(#,JAVA多线程并发编程,AQS,读写锁,JUC)