了解可重入锁

ops/2024/11/9 16:42:45/

1.基本概念:

        可重入锁(Reentrant Lock),又称递归锁(Recursive Lock),是一种在多线程编程中使用的锁机制。它允许同一个线程在持有锁的情况下再次获取它,而不会引起死锁。这在处理递归方法或需要重复进入同步代码块的场景下非常有用。

2.特点:

        (1).可重入性:如果一个线程已经获得了锁,再次请求该锁时不会被阻塞,而是允许其成功获取锁并进入同步代码块。这意味着同一个线程可以多次进入锁保护的代码块。

        (2).计数器机制:可重入锁内部通常维护一个计数器,记录当前线程获取锁的次数。每次锁被获取时,计数器加一;每次锁被释放时,计数器减一。当计数器归零时,锁才真正被释放。

        (3).公平性选项:许多可重入锁实现允许设置“公平”策略,按请求锁的顺序(FIFO)分配锁。非公平锁通常会更高效,因为它减少了上下文切换的次数,但可能导致线程饥饿。

3. 与普通锁的区别:

  • 普通锁(如 Java 的 synchronized:一个线程获得锁后,其他线程尝试获取同一个锁时会被阻塞,即使是同一个线程也不能再次进入同步代码块。
  • 可重入锁:同一个线程可以多次获得同一把锁,不会阻塞自己,但其他线程仍会被阻塞。

4.可重入锁适用于以下场景:

  • 递归方法调用:一个持有锁的方法调用另一个持有相同锁的方法,如果没有可重入锁,线程会被阻塞。
  • 分段操作需要持有锁:在复杂的多线程环境中,一个方法可能会分多个步骤操作共享资源,这时可重入锁能防止出现死锁情况。

5.示例:

java">import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();public void outerMethod() {lock.lock();  // 获取锁try {System.out.println("Outer method executing...");innerMethod();  // 调用内层方法} finally {lock.unlock();  // 释放锁}}public void innerMethod() {lock.lock();  // 线程可以再次获取同一把锁try {System.out.println("Inner method executing...");} finally {lock.unlock();  // 释放锁}}public static void main(String[] args) {ReentrantLockExample example = new ReentrantLockExample();example.outerMethod();}
}

        在这个示例中,outerMethod()innerMethod() 都在同一线程中调用,同一线程可以多次获取同一把锁。

6.优缺点:

        6.1优点

        (1).解决递归调用或同一线程需要多次进入同步代码块的问题。

        (2).可以实现公平锁,避免线程饥饿。

        6.1缺点

        (1).相比于 synchronized,使用更复杂且容易出错(需要显式获取和释放锁)。

        (2).使用不当可能导致死锁。

7.可重入锁的主要解决的问题是:

  • 递归调用中的死锁问题:允许同一个线程多次获取同一把锁。
  • 在多个方法之间共享锁的场景:保持线程在不同方法调用中对同一资源的控制。
  • 更灵活的锁管理:支持可中断的锁获取和公平锁策略。

http://www.ppmy.cn/ops/110312.html

相关文章

风趣图解LLMs RAG的15种设计模式-第三课

设计模式9-重新排名以优化搜索结果 设计模式10-使用上下文压缩优化搜索结果 设计模式11-使用纠正RAG对检索文档打分和过滤 今天先讲这些吧

网络安全应急响应技术原理与应用

网络安全应急响应概述 概念 为应对网络安全事件,相关人员或组织机构对网络安全事件进行监测、预警、分析、响应和恢复等工作 网络安全应急响应组织建立与工作机制 网络安全应急响应预案内容与类型 常见网络安全应急事件场景与处理流程 应急演练:对假定…

pgAdmin 4备份数据库失败,解决

pgAdmin4中,必须先设置二进制路径;binary paths pgAdmin4操作路径,File—>Preferences—>Paths—>Binary paths 找到postgreSQL的安装目录,bin目录复制,然后设置在截图标记位置; 再去备份数据库就…

Unity Apple Vision Pro 开发(五):PolySpatial 2.0 导入方式

文章目录 XR 开发者社区链接: SpatialXR社区:完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子 视频教程: 苹果VisionPro开发 5—PolySpatial2.0导入方式 课程内容: Apple Vision Pro 的 Unity 开发工具 PolySpatial …

postgresql中的各种浮点型小数精度区别

postgresql中的各种浮点型小数精度区别 在PostgreSQL中,FLOAT、NUMERIC(或DECIMAL)和REAL是三种不同的数据类型,它们各自有不同的用途和特性。不过,需要注意的是,PostgreSQL标准数据类型中并没有直接命名为…

Git 提取和拉取的区别在哪

1. 提取(Fetch) 操作说明:Fetch 操作会从远程仓库下载最新的提交、分支信息等,但不会将这些更改合并到你当前的分支中。它只是将远程仓库的更新信息存储在本地,并不会自动修改你当前的工作区。 使用场景: …

Linux驱动.之platform平台总线驱动框架(二),正点原子

第五十四章 platform设备驱动实验 我们在前面几章编写的设备驱动都非常的简单,都是对IO进行最简单的读写操作。像I2C、SPI、LCD等这些复杂外设的驱动就不能这么去写了,Linux系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件…

第143天:内网安全-权限维持自启动映像劫持粘滞键辅助屏保后门WinLogon

案例一: 权限维持-域环境&单机版-自启动 自启动路径加载 路径地址 C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup\ ##英文C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\开始菜单\程序\启动\ ##中文…