深入ReentrantReadWriteLock

简介: 深入ReentrantReadWriteLock

ReentrantReadWriteLock出现的原因

  • 首先synchronized和ReentrantLock都是互斥锁,一个线程在获取锁资源之后另一个线程只能等待
  • 假设有一种情况是读多写少,并且确保线程安全。可以使用ReentrantReadWriteLock实现
  • ReentrantReadWriteLock的特点是读读不互斥,可以并发执行;读写操作则是互斥的。

代码效果显示

/**
 * @author 舒一笑
 * @date 2023/6/1
 */
public class Test17 {

    static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
    static ReentrantReadWriteLock.ReadLock readLock =lock.readLock();

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            // 这里现在是读锁
            readLock.lock();
            try {
                System.out.println("子线程是读锁");
                Thread.sleep(50000000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                readLock.unlock();
            }
        }).start();

        Thread.sleep(1000);
        // 这里现在也是读锁
        readLock.lock();
        try {
            System.out.println("主线程");
        } finally {
            readLock.unlock();
        }

    }
}
  • 读读锁效果演示

  • 写读锁效果演示

ReentrantReadWriteLock(重新输入读写锁定)锁的实现原理分析

  • 还是基于AQS实现,同样都是对state的操作。获取锁资源成功便执行判断之后的方法体逻辑,否则便会阻塞到AQS队列中去排队


  • 查看对AQS方法在ReentrantReadWriteLock中的实现可以知道
  • 读锁操作是基于state的高16位的操作
  • 写锁操作是基于state的低16位的操作,所以在锁重入的时候同样是对state的操作,但是范围却比小了


  • ReentrantReadWriteLock依旧是可重入锁
    tryAcquire(int acquires)方法的分析
  • 当前线程不持有锁资源,c的值是0;尝试获取锁资源、CAS拿锁。


写锁释放锁流程和源码分析

  • tryRelease(arg)方法分析

读锁分析

  • 读锁加锁源码分析
  • 方法体里面没拿到锁资源就去排队

  • tryAcquireShared(arg)方法分析

  • 读锁重入流程分析
  • 读锁的重入主要就是基于下面这部分的源码的实现。
  • 通过对r是否为0的判断来证明当前是不是第一个拿到读锁资源的线程
  • 判断满足那么将firstRead置为当前线程。并将firstReadCount置为1
  • 要是第一个判断不满足。那么便会判断当前线程是不是第一个获取读锁资源的线程。要是是的话那么就会firstReadHoldcount++
  • 要是还是不满足那么就说明当前线程不是第一个获取读锁资源的线程。那就在方法体中获取最后一个拿到锁资源的线程。并判断当前线程是否是最后一个拿到读锁资源的线程。要是不是那就将当前线程设置为cachedHoldCounter。
  • 如果在最内部的判断中当前线程是之前的cachedHoldCounter,那就判断当前的重入次数是不是0,重新设置当前线程锁重入信息到readHolds,就是包装了ThreadLocal中,完成初始化操作。重入次数是0;将count次数++

  • 读锁加锁后续fullTryAcquireShared(current)方法分析

  • 读锁在获取锁资源之后doAcquireShared(arg)方法分析

    setHeadAndPropagate(node, r);方法分析

读锁释放锁流程

  • doReleaseShared()方法分析
目录
相关文章
|
存储 数据库 数据安全/隐私保护
如何使用AnyTXT Searcher+cpolar实现身在异地搜索公司本地电脑文件
如何使用AnyTXT Searcher+cpolar实现身在异地搜索公司本地电脑文件
157 0
|
11月前
|
负载均衡 Java Nacos
Nacos服务注册与发现
【10月更文挑战第11天】Nacos 是一个开源平台,用于服务发现和配置管理,提供服务注册、发现及动态配置等功能,适用于微服务架构。其核心功能包括服务注册、服务发现和动态配置管理,支持多种语言如 Java、Go、Python 等,具备高可用性和易用性。Nacos 可用于微服务治理、动态扩展和跨语言服务调用等场景,简化了服务间的交互和管理。
457 10
|
应用服务中间件 Linux 网络安全
nginx安装的详细教程(包括命令行安装和编译安装)
nginx安装的详细教程(包括命令行安装和编译安装)
|
小程序 开发工具 Android开发
Donut多端框架小程序打包适配ios和安卓app
腾讯新出了一个 Donut 多端框架,可以直接将微信小程序转成 ios 和 安卓 app,小程序开发者工具里也集成了 app 相关升级、调试和打包的功能,终于可以一套代码开发出3个客户端了!
Donut多端框架小程序打包适配ios和安卓app
|
缓存 分布式计算 关系型数据库
MapReduce【mapJoin&reduceJoin】
MapReduce【mapJoin&reduceJoin】
|
Python
想学Python又看不懂英文 ?20秒教会你PyCharm如何设置中文 !
想学Python又看不懂英文 ?20秒教会你PyCharm如何设置中文 !
10453 0
想学Python又看不懂英文 ?20秒教会你PyCharm如何设置中文 !
|
Java 数据安全/隐私保护
EditPlus最新汉化绿色版的下载、破解,以及开发java文件时的一些相关设置操作视频
1.EditPlus v4.30.2555 汉化免费绿色版   下载链接:https://pan.baidu.com/s/1jJUJzUm 密码:xlli   注意:解压后点击 EditPlus.exe 后 ,点击文件夹中的 !激活密钥.reg 注册导入注册表即为无限制注册版(也即免费版)。
1486 0
|
5天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1134 2
|
4天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
658 11