【Java | 多线程】可重入锁的概念以及示例

什么是可重入锁(Reentrant Lock)?

可重入锁(又名递归锁)是一种特殊类型的锁,它允许同一个线程在获取锁后再次进入该锁保护的代码块或方法,而不需要重新获取锁

说白了,可重入锁的特点就是同一个线程可以多次获取同一个锁,而不会因为之前已经获取过锁而阻塞。

可重入锁的一个优点是可以一定程度避免死锁。

举例可重入锁

在Java中,ReentrantLocksynchronized都是可重入锁。

synchronized

public class ReentrantLockDemo {public synchronized void outerMethod() {System.out.println("进入外层方法");innerMethod();System.out.println("退出外层方法");}public synchronized void innerMethod() {System.out.println("进入内层方法");// Do some workSystem.out.println("退出内层方法");}public static void main(String[] args) {ReentrantLockDemo demo = new ReentrantLockDemo();demo.outerMethod();}
}

outerMethod外层方法 中获取锁的线程能够在 innerMethod内层方法 中重新获取同一个锁,而不需要阻塞。

运行结果如下:

进入外层方法
进入内层方法
退出内层方法
退出外层方法

ReentrantLock

import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockDemo {private ReentrantLock lock = new ReentrantLock();public void outerMethod() {lock.lock(); // 获取锁try {System.out.println("进入外层方法");innerMethod();System.out.println("退出外层方法");} finally {lock.unlock(); // 释放锁}}public void innerMethod() {lock.lock(); // 再次获取锁try {System.out.println("进入内层方法");// 执行一些操作System.out.println("退出内层方法");} finally {lock.unlock(); // 释放锁}}public static void main(String[] args) {ReentrantLockDemo demo = new ReentrantLockDemo();demo.outerMethod();}
}

Synchronized可重入的实现原理

事实上,每个锁对象拥有一个锁计数器和一个指向持有该锁的线程的指针。

当执行 monitorenter 指令时,如果目标锁对象的计数器为零,那么说明它没有被其他线程所持有,Java 虚拟机会将该锁对象的持有线程设置为当前线程,并且将其计数器加 1。

在目标锁对象的计数器不为零的情况下,如果锁对象的持有线程是当前线程,那么 Java 虚拟机可以将其计数器加 1,这是因为锁是可重入的,当前线程可以多次获取同一个锁。否则,如果锁对象的持有线程不是当前线程,那么当前线程需要等待,直至持有线程释放该锁。

当执行 monitorexit 指令时,Java 虚拟机则需将锁对象的计数器减 1。如果计数器减到零,那么锁就被释放了。

monitorentermonitorexit 指令是 Java 字节码中的指令,它们是由 Java 编译器生成的。

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

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

相关文章

互联网和嵌入式,哪个更吃香?

在开始前我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!显然,互联网更受青…

地形系统-unity3D地形的生成原理和地形表面贴图的混刷原理

Unity3D地形的生成原理是通过使用高度图来创建地形。高度图是一个灰度图像,其中每个像素的灰度值表示该位置的高度。在Unity中,可以使用工具或编程方式创建高度图,然后将其应用于地形对象。 地形表面贴图的混刷原理是通过将多个纹理图层叠加…

No.1 - 职场关键角色通识宝典之课程内容先导

📖 该文隶属 程序员:职场关键角色通识宝典 ✍️ 作者:哈哥撩编程(视频号同名) 博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 🏆 推荐专栏…

Mysql全局优化总结

Mysql全局优化总结 从上图可以看出SQL及索引的优化效果是最好的,而且成本最低,所以工作中我们要在这块花更多时间 服务端系统参数 官方文档:https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_connections…

MSE实现全链路灰度实践

技术架构包括以下基础设施和云服务: 1个地域:ACK集群、微服务应用、MSE实例均部署在同一地域下。 1个专有网络VPC:形成云上私有网络,确保核心云资源的网络环境,如容器服务ACK、微服务引擎MSE。 ACK集群:简单…

七星创客新零售系统:颠覆性商业模式的崛起

大家好,我是微三云周丽,今天给大家分析当下市场比较火爆的商业模式! 小编今天跟大伙们分享什么是七星创客新零售系统? 随着经济的快速发展和科技的不断进步,商业模式的革新成为了企业发展的关键。在这个新旧动能转换、…

CentOS配置JDK8环境并安装配置neo4j

1. 工具安装 1. 安装wget yum install -y wget2. 安装vim yum install -y vim-enhanced2. 配置JDK 1. 安装JDK 先到官网下载jdk8的压缩包,点我传送,并将压缩包上传到虚拟机的/usr/local目录下。 cd /usr/local # 进入 /usr/local目录 tar -zxvf jdk-…

使用Perf诊断PostgreSQL性能问题

1 编译参数 使用perf获取完整的堆栈信息需要下面几个编译参数: -O0:编译器不做优化-ggdb3:增加了为GDB优化的调试信息,级别是3-g3:增加了调试信息,级别是3-fno-omit-frame-pointer:保留完成的…

「JavaEE」线程状态

🎇个人主页:Ice_Sugar_7 🎇所属专栏:JavaEE 🎇欢迎点赞收藏加关注哦! 线程状态 🍉start 和 run 的区别🍉终止线程🍉join & 阻塞状态🍉线程六大状态 &…

Java离线视频提取音频+音频提取文案

需引入依赖javacv、vosk相关依赖, 至于javacv依赖,网上有很多缩减方案,注释部分是可行的缩减方案,至于视频提取视频这里无需安装ffmpeg,只需引入依赖。而vosk需要下载模型方可使用,并且下载比较慢&#xf…

docker 基本命令

目录 一、docker 镜像操作命令 1.1.查询软件镜像 1.2.docker pull:下载镜像 1.3.docker push:上传镜像 1.4.docker images:查看本地镜像 1.5.docker inspect :获取镜像详细信息 1.6.docker tag:添加镜像标签 …

tornado模板注入

这是我在做一道ctf题目当中遇到的,不太会,所以浅浅学习了一下,跟大家分享。 1.介绍 tornado是python当中的一个模板,因此这个漏洞是归属于SSTI(服务器模板漏洞),所谓的模板其实就是一种框架,p…

L2-052 吉利矩阵

所有元素为非负整数,且各行各列的元素和都等于 7 的 33 方阵称为“吉利矩阵”,因为这样的矩阵一共有 666 种。 本题就请你统计一下,把 7 换成任何一个 [2,9] 区间内的正整数 L,把矩阵阶数换成任何一个 [2,4] 区间内的正整数 N&…

Git:使用conda命令切换虚拟环境

1. 问题 在win10电脑的Git中,无法使用conda list命令,报错(bash:conda:command not found)。也无法使用conda activate base命令激活虚拟环境,报错(bash:conda&#xff…

pollLast() 和poll啥区别

在 Java 中,pollLast() 和 poll() 是 Deque 接口的两个不同的方法,它们都用于从双端队列中移除并返回元素,但它们移除元素的位置不同: poll(): poll() 方法从双端队列的前端移除并返回第一个元素(即队列的头部&#xf…

共享单车数据分析与需求预测项目

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 ([www.aideeplearning.cn]) 项目背景 自动自行车共享系统是传统自行车租赁的新一代,整个会员、租赁和归还过程都变得自动化。通过这些系统,用户可以…

C# ToString

你可以创建自定义数字格式字符串,这种字符串由一个或多个自定义数字说明符组成,用于定义设置数值数据格式的方式。 自定义数字格式字符串是任何不属于 标准数字格式字符串的格式字符串。 自定义数字格式字符串

【c++】cpp类和对象

(1)类的封装 封装的多层含义 把属性和⽅法进⾏封装对属性和⽅法进⾏访问控制类的内部和类的外部类的访问控制关键字 public: 修饰的成员变量和函数,可以在类的内部和类的外部访问private: 修饰的成员变量和函数,只能在类的内部…

L1-098 再进去几个人 - java

L1-098 再进去几个人 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB 题目描述: 数学家、生物学家和物理学家坐在街头咖啡屋里,看着人们从街对面的一间房子走进走出。他们先看到两个人进去。时光流逝。他们又看到三个人出来。 物理…

锐捷网络闪耀高博会:智慧教育数字基座引领教育数字化新浪潮

4月15日,第61届中国高等教育博览会(简称“高博会”)在福州盛大开幕,在这次教育高端装备展示、教学改革成果交流、校企云集的行业盛会上,围绕构建智慧教育数字基座,锐捷网络携全场景智慧教育方案亮相,极简以太全光网、高校桌面云、5G多网融合等创新方案纷纷登场,吸引了众多观众驻…