浅谈可重入锁

2023-10-29

一、可重入锁(递归锁)

1、概念:同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是:锁对象是同一个对象),不是因为之前已经获取过还没有释放而阻塞

2、java中的ReentrantLock和synchronied都是可重入锁,可重入锁的一个优点就是可以在一定程度上避免死锁的出现

二、可重入锁的种类

一、隐式锁(Synchronized关键字使用的锁)默认是可重入锁

public class ReEnterLockDemo {
    public synchronized void m1(){
        System.out.println("外");
        m2();//当获取到锁时,由于是同一个对象,所以在进入m2时可以直接进入,这就是可重入锁
    }
    public synchronized void m2(){
        System.out.println("中");
        m3();
    }
    public synchronized void m3(){
        System.out.println("内");
    }
    public static void main(String[] args) {
        new ReEnterLockDemo().m1();
    }
}

Synchronized的重入实现机制:

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

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

(进入另一个带锁的方法或代码块中)在锁对象的计数器不为零的情况下,如果锁对象的持有线程是当前线程,那么java虚拟机可以将其计数器加一,否则需要等待,直至持有线程释放该锁。

当执行monitorexit时,java虚拟机则需要将锁对象计数器减一,当锁对象计数器为零时,代表锁已被释放。

二、显式锁(即Lock锁)也有ReentranLock这样的可重入锁

public class ReEnterLockDemo2 {
    static Lock lock = new ReentrantLock();
    public static void main(String[] args) {

        new Thread(()->{
            lock.lock();
            try {
                System.out.println("外层");
                lock.lock();
                try {
                    System.out.println("中层");
                }finally {
                    lock.unlock();//加几次锁就要释放几次锁
                }
            }finally {
            lock.unlock();
            }
        }).start();
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈可重入锁 的相关文章

随机推荐

  • C++预处理详解

    本文在参考ISO IEC 14882 2003和cppreference com的C Preprocessor的基础上 对C 预处理做一个全面的总结讲解 如果没有特殊说明 所列内容均依据C 98标准 而非特定平台相关 如VC 的 C 11新
  • 求两条轨迹间的hausdorff距离_轨迹数据压缩的DouglasPeucker算法

    点击蓝字关注我们 交通数据中会有很多的轨迹数据 轨迹数据一般是按秒采集 所以轨迹数据的量都是很大的 但是在进行数据分析时 轨迹数据量太大会影响运算效率 而且很多轨迹点是没有必要分析的 所以需要对数据进行压缩 轨迹数据压缩技术的主要目标是在不
  • open-api 算法实现

    要求 推荐在openEuler中实现 参考https www cnblogs com rocedu p 6012545 html第三节 提交相关代码码云 或github 链接 我使用博客园 提交不少于6张编译测试过程截图 至少包含SM4 S
  • 在C++中子类继承和调用父类的构造函数方法

    构造方法用来初始化类的对象 与父类的其它成员不同 它不能被子类继承 子类可以继承父类所有的成员变量和成员方法 但不继承父类的构造方法 因此 在创建子类对象时 为了初始化从父类继承来的数据成员 系统需要调用其父类的构造方法 如果没有显式的构造
  • 架构知识体系

    架构安全 对已知问题有有效的解决方案 对未知 潜在问题建立发现和防御机制 对于安全问题 首先要提高安全意识 建立一个安全的有效机制 从政策层面 组织层面进行保障 比如服务器密码不能泄露 密码每月更新 并且三次内不能重复 每周安全扫描等 以制
  • Gradle Springboot Web热部署的设置

    前言 在我们平时开发当中 需要实时的要查看我们的编码效果 这个时候如果我们设置了热部署 就免去了我们频繁的重启本地项目 热部署我们需要用到spring boot devtools这个组件 这里我们采用的gradle来管理项目 所以采用的ma
  • LeetCode 226. 翻转二叉树

    题目链接 https leetcode cn com problems invert binary tree 先序遍历 Java 代码 class Solution public TreeNode invertTree TreeNode r
  • 我的世界ess服务器信息,我的世界ess指令怎么用 ess指令大全及用法详解

    我的世界ess指令都有哪些 作为风靡全球的沙盒游戏 我的世界带给玩家太多的乐趣 为了能更方便的游戏 ess指令能帮助我们更好的游戏 很多新手玩家刚接触就被搞晕了 这么多的指令看起来有些复杂 下面就由小编给大家带来 我的世界ess指令都有哪些
  • mybatis进行批量插入 返回批量插入主键ID 插入不成功等问题

    这篇博文讲的是批量插入的例子 dao层框架用的mybatis 最一开始我的批量插入其实是个伪批量 是类似吧很多条insert into语句 直接拼成一条 然后直接运行 发现这样的效率真的是十分低 我做测试时285条数据 插入一次需要10S多
  • uniapp添加.gitignore以及不生效解决办法

    一 第一次新建 gitignore 首先进入项目 命令行新建 gitignore文件 touch gitignore 然后编辑器打开 进入到项目中新建的 gitignore 文件 复制粘贴以下 node modules project un
  • C++实现鼠标点击其他程序

    1 主要是SendInput函数 代码如下 初始化 INPUT input 0 input type INPUT MOUSE dx dy代表的是进行点击的坐标 下面显示的是 950 150 input mi dx static cast
  • 【Proteus仿真】555组成的多谐振荡器电路

    Proteus仿真 555组成的多谐振荡器电路 Proteus仿真演示 多谐振荡器电路 多谐振荡器电路是一种矩形波产生电路 属于数字电路 三极管不工作在放大线性区 这种电路不需要外加触发信号便能连续地 周期性地自行产生矩形脉冲 该脉冲是由基
  • Stable Diffusion:ChatGPT与AI绘画,引领艺术的未来

    人工智能 AI 的快速发展正在为各个领域带来革命性的变化 其中包括艺术与创意领域 AI绘画是一种将人工智能技术与艺术创作相结合的新兴范式 通过深度学习和生成对抗网络 GAN 等技术 AI绘画可以生成各种富有创意和想象力的艺术作品 本文将探讨
  • python - __str__ 和 __repr__

    内建函数str 和repr representation 表达 表示 或反引号操作符 可以方便地以字符串的方式获取对象的内容 类型 数值属性等信息 str 函数得到的字符串可读性好 故被print调用 而repr 函数得到的字符串通常可以用
  • Docker+docker-compose+nginx部署已有项目

    项目背景 在异地服务器拷docker相关项目到新的服务器 具体操作 1 新服务器安装好docker 2 新服务器安装好docker compose 3 从老服务器拷贝镜像到新服务器 4 新服务器导入镜像 5 构建项目地址挂载目录 找到doc
  • 用U盘作启动盘装Windows10系统整套流程 纯净版(不用其他乱七八糟的软件)(macOS适用)

    简介 本人的电脑是MacBook Air 2014年版的 因为内存小而且文件杂乱 所以一下子都给格式化了 但是要用Mac自带的恢复系统的话需要连接校园网 连接校园网又需要打开网页输入账号和密码 我们学校的校园网是这样的 所以只能用U盘作为格
  • gqrx编译过程记录

    gqrx编译过程记录 目标 环境 编译 下载源代码 建立编译位置 修改CMakefile txt中的模块 编译安装 运行界面 没有更多 目标 在ubuntun 20 04桌面版编译gqrx 通过USRP 205mini实现收音机功能 环境
  • 【解决】docker容器怎么使用宿主机的IPv6地址

    在IPv4时代 我们对外访问都是端口映射 都没有公网IP 但是在IPv6时大家都有公网IP 可能需要容器地址和主机地址一致 可以在docker run时使用参数 network host 则此容器网络和宿主机一致 docker run ne
  • AQS详解

    AQS详解 文章目录 AQS详解 AQS简单介绍 AQS原理 AQS原理概览 AQS对资源的共享方式 AQS定义两种资源共享方式 Exclusive 独占 Share 共享 AQS底层使用了模板方法模式 Semaphore 信号量 Coun
  • 浅谈可重入锁

    一 可重入锁 递归锁 1 概念 同一个线程在外层方法获取锁的时候 再进入该线程的内层方法会自动获取锁 前提是 锁对象是同一个对象 不是因为之前已经获取过还没有释放而阻塞 2 java中的ReentrantLock和synchronied都是