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

ops/2024/9/25 21:28:40/

什么是可重入(Reentrant Lock)?

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

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

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

举例可重入

在Java中,ReentrantLocksynchronized都是可重入

synchronized

java">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

java">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.ppmy.cn/ops/13774.html

相关文章

debian配置distcc分布式编译

前言 distcc 是一个用于在网络上的多台机器上分发 C、C、Objective C 或 Objective C 代码构建的程序。 distcc 应始终生成与本地构建相同的结果,易于安装和使用,并且通常比本地编译快得多。 distcc 不要求所有机器共享文件系统、同步时钟或安装相同的…

Linux--系统烧写

前面几篇文章,已经搞定了Linux移植三巨头:uboot、kernel(包含dtb)和rootfs,除了uboot是烧写在SD中的,其它的都是在ubuntu虚拟机的nfs服务器中,运行时必须通过网络将这些文件加载到开发板的内存中运行。 本篇就来研究&a…

带头双向循环链表的基本操作(c语言实现)

带头双向循环链表 带头双向循环链表是一种结合了双向链表和循环链表特性的数据结构。其主要特点如下: 双向性:链表中的每个节点都有两个指针,一个指向下一个节点(next),另一个指向前一个节点(p…

C语言操作符和关键字

文章目录 操作符单目操作符sizeof(类型)强制类型转换 关系操作符、逻辑操作符、条件操作符逗号表达式 常见关键字typedefstaticstatic修饰局部变量static修饰全局变量static修饰函数 register寄存器关键词define定义常量和宏 操作符 单目操作符 C语言中…

前缀和 求数列的子序列的K倍区间

(直接截图比复制文字要好多了) 不会做的时候我去看了之前做的关于这道题目的笔记, (Ak 1)% k 1 (Ak 1 Ak)% k 1 只要发现了同余数的情况就说明有一个区间满足了题目的要求。 这个方法的精妙之处就在于前缀和包括了…

背靠TON公链的Notcoin游戏项目,能否杀出GameFi的红海?

4月15日消息,Telegram生态中的游戏及Meme项目Notcoin,最近在X平台公布了令市场瞩目的代币经济学方案。据悉,NOT的总供应量高达1027亿枚,其中78%将分配给矿工和Voucher持有者,余下的22%预留给未来新用户、交易者及各类上…

【Linux驱动层】iTOP-RK3568学习之路(五):并发与竞争

本人在听讯为的课时,哪怕是照抄,编译后,这里的代码执行不了,只能做笔记了。 一、原子操作 ​ 借用原子是"化学反应中最小的微粒“这个概念,用原子来表述—个操作是不可以被打断,拆分的操作。简单&…

迪拜Token2049展会圆满落幕,MVP成唯一MEMECOIN项目,闪耀全场!

近日,据多家媒体报道,于全球财富聚集地迪拜举行的全球性大型区块链会议TOKEN2049圆满落幕。来自全球的5000多家公司和100多个国家10000名参与者共同参会,讨论未来30年至50年关于区块链行业的宏大未来。 新晋MEMECOIN项目MAGA VP(…