ReentrantReadWriteLock不能锁升级的原因总结

 更新时间:2021年06月30日 11:18:50   作者:skyline_wx  
今天给大家带来的是关于Java并发的相关知识,文章围绕着为什么ReentrantReadWriteLock不能锁升级展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下

为什么ReentrantReadWriteLock不能锁升级

ReentrantReadWriteLock中,锁是不可以升级的,只能降级。

也就是如果当前线程持有了ReadLock,那么就不能再获取WriteLock,但是,如果当前线程持有了WriteLock,可以直接获取ReadLock

下面用代码尝试一下:

Logger logger = LoggerFactory.getLogger(this.getClass());
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
logger.info("线程:[{}],开始readLock",Thread.currentThread().getName());
readLock.lock();
logger.info("线程:[{}],readLock成功",Thread.currentThread().getName());
logger.info("线程:[{}],开始writeLock",Thread.currentThread().getName());
writeLock.lock();
logger.info("线程:[{}],writeLock成功",Thread.currentThread().getName());

从打印结果可以看出来,程序阻塞在了writeLock.lock();这一行上。

锁升级失败

下面我们看一下WriteLock的加锁过程的部分源码:

java.util.concurrent.locks.ReentrantReadWriteLock.Sync#tryAcquire

tryAcquire

当这个tryAcquire返回false时,就跟ReentrantLock的逻辑差不多了,最后各种判断条件都会失败,最后,程序会阻塞在这里:java.util.concurrent.locks.AbstractQueuedSynchronizer#parkAndCheckInterrupt

parkAndCheckInterrupt

用流程图来描述一下这个问题是这样的:

在这里插入图片描述

假如只有一个线程t1,当t1已经获取读锁之后,再次获取写锁,因为写锁在加锁时判断到当前锁已经被加过读锁读写互斥,所以写锁会等待读锁释放之后再加锁。但是因为读锁是被当前线程持有的,所以这个等待会无限的等待下去,最后就成了死锁。

到此这篇关于ReentrantReadWriteLock不能锁升级的原因总结的文章就介绍到这了,更多相关ReentrantReadWriteLock不能锁升级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 自定义线程池和线程总数控制操作

    Java 自定义线程池和线程总数控制操作

    这篇文章主要介绍了Java 自定义线程池和线程总数控制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • RocketMQ事务消息原理与使用详解

    RocketMQ事务消息原理与使用详解

    RocketMQ事务消息(Transactional Message)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败。RocketMQ的事务消息提供类似 X/Open XA 的分布式事务功能,通过事务消息能达到分布式事务的最终一致
    2023-02-02
  • Spring Cloud Alibaba Nacos Config加载配置详解流程

    Spring Cloud Alibaba Nacos Config加载配置详解流

    这篇文章主要介绍了Spring Cloud Alibaba Nacos Config配置中心实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-07-07
  • JDK14的新特性:instanceof模式匹配的使用

    JDK14的新特性:instanceof模式匹配的使用

    这篇文章主要介绍了JDK 14的新特性:instanceof模式匹配的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • SpringBoot集成EasyExcel的步骤

    SpringBoot集成EasyExcel的步骤

    EasyExcel是阿里巴巴开源poi插件之一,主要解决了poi框架使用复杂,sax解析模式不容易操作,数据量大起来容易OOM,解决了POI并发造成的报错。主要解决方式:通过解压文件的方式加载,一行一行的加载,并且抛弃样式字体等不重要的数据,降低内存的占用。
    2021-06-06
  • java基于NIO实现群聊模式

    java基于NIO实现群聊模式

    这篇文章主要为大家详细介绍了java实现NIO实现群聊模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • MyBatis-Plus介绍及Spring Boot 3集成指南

    MyBatis-Plus介绍及Spring Boot 3集成指南

    本文介绍了MyBatis-Plus的基本特性及其与Spring Boot 3的集成步骤,通过使用MyBatis-Plus,开发者可以快速地搭建和开发数据访问层,同时提高代码质量和开发效率,感兴趣的朋友一起看看吧
    2024-05-05
  • Java实现常用的三种加密算法详解

    Java实现常用的三种加密算法详解

    编程中常见的加密算法有以下几种:信息摘要算法、对称加密算法以及非对称加密算法。本文将利用Java实现这几种常见的加密算法,需要的可以参考一下
    2022-03-03
  • JAVA多线程线程安全性基础

    JAVA多线程线程安全性基础

    这篇文章主要介绍了如何测试Java类的线程安全性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-08-08
  • MyBatis-plus如何执行自定义SQL

    MyBatis-plus如何执行自定义SQL

    这篇文章主要介绍了MyBatis-plus如何执行自定义SQL问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02

最新评论