Java并发编程中的ReentrantLock类详解

 更新时间:2023年12月12日 10:16:22   作者:程光CS  
这篇文章主要介绍了Java并发编程中的ReentrantLock类详解,ReentrantLock是juc.locks包中的一个独占式可重入锁,相比synchronized,它可以创建多个条件等待队列,还支持公平/非公平锁、可中断、超时、轮询等特性,需要的朋友可以参考下

一、ReentrantLock介绍

ReentrantLock是juc.locks包中的一个独占式可重入锁,相比synchronized,它可以创建多个条件等待队列,还支持公平/非公平锁、可中断、超时、轮询等特性。

ReentrantLock实现Lock接口实现了一个锁所需的方法,如lock()、unLock()等,在这些方法中实际上是调用继承了AQS的同步器Sync对象中的方法来实现对锁资源的获取与释放,而内部类Sync有两个子类FairSync和NonfairSync,分别对应公平锁和非公平锁。ReentrantLock默认构造器是构造非公平锁

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、ReentrantLock特性详解

1. 多条件队列

Sync对象中开放了创建AQS中条件队列ConditionObject对象的方法,并重写了isHeldExclusively()方法(通知方法signal()要用到),因此可创建条件队列实现通知等待机制。

在这里插入图片描述

2. 非公平 & 公平锁

非公平锁NonfairSync 新进来的线程会先直接与同步队列中的线程竞争CAS竞争失败则调用acquire -> tryAcquire -> nonfairTryAcquire继续竞争,再失败才会在acquire方法中后续执行加入同步队列若线程是重入这个锁,会记录重入次数,若超过int范围溢出则抛出错误

在这里插入图片描述

在这里插入图片描述

公平锁FairSync 新来的线程若同步队列为空才竞争锁,否则tryAcquire直接返回false然后进入队列排队,实现先来后到公平锁同样也会记录重入次数

在这里插入图片描述

3. 可中断

我们知道synchronized在锁竞争时是不可中断的,获取不到锁的线程会一直处于阻塞状态。

ReentrantLock调用lockInterruptibly()获取锁的过程是可以响应中断的,其内部调用的是AQS的acquireInterruptibly()方法

当收到中断信号时会退出阻塞然后抛出InterruptedException异常从而退出锁竞争。

4. 超时

调用tryLock(long timeout, TimeUnit unit)获取锁可实现超时功能,当超过时间还未获取到锁则直接抛出异常退出锁竞争

在这里插入图片描述

内部是AQS中调用LockSupport.parkNanos()超时阻塞实现的

5. 轮询

ReentrantLock的轮询特性是指可通过tryLock()方法尝试获取锁,没获取到则不阻塞直接退出,可以过会再来尝试。tryLock()调用Sync中定义的nonfairTryAcquire方法,从前面列出的源码可知没获取到则直接返回false

在这里插入图片描述

三、ReentrantLock类和synchronized关键字的区别

ReentrantLock和synchronized都是独占式可重入锁,但是它们有如下区别:

  • 锁实现机制:ReentrantLock是一个类,是基于AQS实现的,依赖于JDK的API;synchronized是一个关键字,是直接在JVM层面通过监视器实现的锁机制。
  • 条件等待队列:ReentrantLock通过Condition可创建多个条件等待队列;而synchronized依赖的监视器模型中只有一个等待队列。
  • 非公平 & 公平锁:ReentrantLock支持公平和非公平锁;synchronized为非公平锁
  • 其他特性:ReentrantLock还支持可中断、超时、轮询等特性;synchronized不支持这些
  • 底层原理:ReentrantLock是基于CAS实现共享资源同步,synchronized底层是基于互斥量实现的

一般来说在不需要用到ReentrantLock特殊特性的时候就用synchronized,因为synchronized显然相对来说使用起来更加简洁高效

到此这篇关于Java并发编程中的ReentrantLock类详解的文章就介绍到这了,更多相关Java的ReentrantLock类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java回调函数与观察者模式实例代码

    Java回调函数与观察者模式实例代码

    这篇文章主要介绍了Java回调函数与观察者模式实例代码,简单介绍了使用观察者模式的场景,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Java基础之文件和目录操作

    Java基础之文件和目录操作

    这篇文章主要介绍了Java基础之文件和目录操作,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • Java IO流对象的序列化和反序列化实例详解

    Java IO流对象的序列化和反序列化实例详解

    这篇文章主要介绍了Java IO流对象的序列化和反序列化实例详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • java使用minio上传下载文件完整版教程

    java使用minio上传下载文件完整版教程

    本示例教程介绍了如何使用SpringBoot框架结合MinIO服务实现文件的上传和下载功能,并将文件信息存储在数据库的file表中,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • Spring Boot应用启动时自动执行代码的五种方式(常见方法)

    Spring Boot应用启动时自动执行代码的五种方式(常见方法)

    Spring Boot为开发者提供了多种方式在应用启动时执行自定义代码,这些方式包括注解、接口实现和事件监听器,本文我们将探讨一些常见的方法,以及如何利用它们在应用启动时执行初始化逻辑,感兴趣的朋友一起看看吧
    2024-04-04
  • 解读CommandLineRunner和@PostConstruct区别与应用场景

    解读CommandLineRunner和@PostConstruct区别与应用场景

    这篇文章主要介绍了解读CommandLineRunner和@PostConstruct区别与应用场景,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java下载远程服务器文件到本地(基于http协议和ssh2协议)

    Java下载远程服务器文件到本地(基于http协议和ssh2协议)

    这篇文章主要介绍了Java下载远程服务器文件到本地的方法(基于http协议和ssh2协议),帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2021-01-01
  • POI导出Excel报错No such file or directory的解决方法

    POI导出Excel报错No such file or directory的解决方法

    这篇文章主要为大家详细介绍了POI导出Excel报错No such file or directory的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Java中使用正则表达式的详细教程

    Java中使用正则表达式的详细教程

    本文介绍Java正则表达式基础语法及使用方法,涵盖Pattern/Matcher类、字符匹配、量词、分组、预定义类、转义规则及性能优化建议,提供邮箱、手机号、身份证、URL等常见验证示例,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • Java中的六种经典比较排序算法

    Java中的六种经典比较排序算法

    排序算法是程序开发和计算机科学中常见的算法之一,排序算法是算法分析的重要内容之一,因为排序算法的效率影响着程序的性能和稳定性,本文的目的是介绍常见的排序算法,并且通过代码示例演示它们的实现过程,需要的朋友可以参考下
    2023-06-06

最新评论