Java并发编程(10) —— ReentrantLock类详解

news2024/11/16 23:58:37

一、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都是独占式可重入锁,但是它们有如下区别:

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

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

参考:https://blog.csdn.net/zhengzhaoyang122/article/details/110847701

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS基础特性

一、CSS概述 1.1、概述 CSS(层叠样式表)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS 不仅可以静态地修饰网页,还可以配合…

[JVM] 3. 类加载子系统(2)-- 类加载器、双亲委派机制(JDK1.8及之前)及其他

前言 JDK1.8及之前和JDK9及之后的双亲委派模型是不一样的&#xff0c;这里学习了1.8及以前的双亲委派模型&#xff0c;记录笔记 一、类加载器 1.8之前主要是这几种类加载器&#xff1a; 1. 启动类加载器(Bootstrap ClassLoader)&#xff1a; 负责将存放在<JAVA_HOME>…

JavaScript中值和变量

值是指可以存储在计算机内存中的数据。这些数据可以是数字、字符串、布尔值、对象等。变量是一种用于存储值的容器。 ● 在JS中&#xff0c;我们可以使用let参数也创建一个变量&#xff0c;使用给变量赋值&#xff0c;例如 let ITshare "IT知识一享";● 之后我们打…

力扣小技巧:如何用最简单的方式实现小写字母转换

本篇博客会讲解力扣“709. 转换成小写字母”的解题思路&#xff0c;这是题目链接。 本题的解法非常简单&#xff0c;只需利用tolower函数即可。这个函数的作用是将所有大写字母转换为小写字母&#xff0c;而对其他字符不做任何改变。 char * toLowerCase(char * s){// 把字符串…

1769_Source Insight数字前缀后缀乱码解决方法

全部学习汇总&#xff1a; GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 这算是一个偶然的发现&#xff0c;写代码的时候发现十六进制的数字显示前缀0x显示错误。如果只输入一个0x正常&#xff0c;写成一个十六进制数据诸如0x123之后…

分析中心常见的协议字段以及语法

布尔运算符 基本语法 图中以及描述得很详细了。 日志检索高级查询语法 通配符查询&#xff1a;在一项内的单个字符用&#xff1f;去查&#xff0c;多个字符用*去查询&#xff0c;例如想查mysql和mssql就可以使用db_type:m?sql 去查询&#xff0c;而要查sql结尾就用 *sql 去…

SQL Server启用sa账户

一、简介 在安装好 SQL Server 后&#xff0c;默认 sa 用户是禁用且也没有启用 SQL Server 登陆验证&#xff0c;这需要手动开启。接下来&#xff0c;开始我们今天的教程吧。 二、sa 登陆 2.1 启用 sa 首先&#xff0c;使用 Windows 验证登陆 登陆成功后&#xff0c;找到…

Java032——反射(Reflection)

一、Java中的反射及作用 Java的反射(reflection)机制是指在程序的运行状态中&#xff1a; 可以构造任意一个类的对象&#xff0c;可以了解任意一个对象所属的类&#xff0c;可以了解任意一个类的成员变量和方法&#xff0c;可以调用任意一个对象的属性和方法。 一句话&#…

数据结构day2(2023.7.15)

一、Xmind整理&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;定义车的信息&#xff1a;品牌&#xff0c;单价&#xff0c;颜色&#xff0c;车牌号 struct Car{char name[20]; //品牌int price; //单价char color[10] //颜色char id[20] //车牌…

Spring【 Spring整合MyBatis、SpringAOP(AOP简介 、AOP相关术语、AOP入门)】(五)-全面详解(学习总结---从入门到深化)

目录 Spring整合MyBatis_准备数据库和实体类 Spring整合MyBatis_编写持久层接口和service类 Spring整合MyBatis_Spring整合Junit进行单元测试 Spring整合MyBatis_自动创建代理对象 SpringAOP_AOP简介 SpringAOP_AOP相关术语 SpringAOP_AOP入门 Spring整合MyBatis_准备数据…

推荐几个github上非常受欢迎的库

推荐几个github上非常受欢迎的库 The Book of Secret Knowledge the-book-of-secret-knowledge 这个仓库里边包含了一系列非常有趣的手册、备忘单、博客、黑客、单行话、cli/web 工具等。 Coding Interview University coding-interview-university 这里列出的项目可以帮助…

基于Ubuntu20.4的TMS320C6678开发环境(CCS8.3.1)的搭建

网上关于ccs的安装大多是基于ccs5及以前的版本安装介绍或基于windows版本的ccs软件的安装,没有关于linux系统上安装CCS8.3.1的集成开发环境。本文介绍在ubuntu20.4的系统上安装ccs8.3.1的DSP开发环境&#xff0c;本文包括CCS软件和插件的下载&#xff0c;安装。本文在ubuntu20.…

fpga下载程序到flash后无法在重新上电后自动加载程序

可能是接的调试器没有断电&#xff0c;断电一次再给调试器上电。如果调试器一直连着可以连续断电上电fpga开发板&#xff0c;直到成功。fpga貌似上电后什么程序都不加载则引脚为高电平&#xff0c;而vivado默认.xdc的BITSTREAM.CONFIG.UNUSEDPIN&#xff08;未使用的引脚&#…

vue3 - 01搭建工程

1. 使用vue-cli创建工程 1. 命令&#xff1a;vue create xxx2. 选择vue3版本3. 进入目录4. 运行&#xff1a; npm run serve 在执行完运行指令后如果报错请查看是否是以下错误&#xff0c;如果是可以按以下步骤进行解决&#xff1a; ERROR in Conflict: Multiple assets emit …

命令执行绕过

首先以一道BUUCTF题目来开下胃 查看flag&#xff1a; 其次给大家上主菜-----命令执行绕过 命令执行漏洞绕过方式&#xff1a; 管道符 windows中常见管道符&#xff1a; | 直接执行后面的语句 || 如果前面命令是错的那么就执行后面的语句&#xff0c;否则只执行前面的语…

DEV C++ 更改界面语言

第一步&#xff1a;选中tools&#xff0c;然后从里面找Environment optional 第二步&#xff1a;从里面找到Language选项&#xff0c;找到简体中文 选中简体中文后点击“OK”就可以了

go语言 socket: too many open files 错误分析

问题背景&#xff1a; 近期针对老的PHP接口做了迁移重构&#xff0c;用golang重新实现&#xff0c;在上线之前&#xff0c;测试进行了压测&#xff0c;压测的量级为&#xff1a;200请求/s, 连续请求10s&#xff0c;发现接口出现大量超时错误&#xff0c;查看日志发现错误信息为…

前缀和模板算法

一)模板前缀和 【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 前缀和:快速的得出数组中某一段连续区间的和 暴力破解的话需要从头到尾的进行遍历&#xff0c;时间复杂度就可以达到O(N)&#xff0c;而前缀和时间复杂度是可以达到O(1)的 第一步:预处理创建出一个前缀和数组dp&a…

RTMP简介

简介 RTMP协议是Real Time Message Protocal(实时传输协议的缩写)&#xff0c;同时Adobe公司提供的一种应用层协议&#xff0c;用来解决多没意思数据流传输的 多路复用和分包问题。 RTMP是应用层协议&#xff0c;采用TCP来保证可靠的传输在TCP完成握手连接建立后&#xff0c…

【动手学深度学习】--03.多层感知机MLP

文章目录 多层感知机1.原理1.1感知机1.2多层感知机MLP1.3激活函数 2.从零开始实现多层感知机2.1初始化模型参数2.2激活函数2.3 模型2.4损失函数2.5训练 3.多层感知机的简洁实现3.1模型3.2训练 多层感知机 1.原理 官方笔记&#xff1a;多层感知机 1.1感知机 训练感知机 收敛定…