Java可重入锁的实现示例

 更新时间:2024年02月23日 10:14:57   作者:自信人间三百年  
在java中,可重入锁分为两种,即synchronized锁以及ReentrantLock及其实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧

什么是可重入锁?

当线程获取某个锁后,还可以继续获取它,可以递归调用,而不会发生死锁;

image-20230728110933738

可重入锁案例

程序可重入加锁 A.class,没有发生死锁。

sychronized锁

package com.wnhz.lock.reentrant;

public class SychronizedDemo {

    class A {
        void a() {

        }
    }

    class B {
        void b() {
        }
    }

    public static void main(String[] args) {
        System.out.println("准备锁住class A >>>>");
        synchronized (A.class) {
            System.out.println("锁住class A--> 成功");
            System.out.println("准备再次锁住class A >>>>");
            synchronized (A.class) {
                System.out.println("锁住class A--> 成功");
            }
            System.out.println("释放class A");
        }
    }
}

运行结果

准备锁住class A >>>>
锁住class A--> 成功
准备再次锁住class A >>>>
锁住class A--> 成功
释放class A

ReentrantLock

package com.wnhz.lock.reentrant;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {

    private static final Lock lock = new ReentrantLock();
    class A {
        void a() {
        }
    }

    class B {
        void b() {
        }
    }

    public static void main(String[] args) {
        System.out.println("准备锁住class A >>>>");
        lock.lock();
        try {
            System.out.println("锁住class A--> 成功");
            System.out.println("准备再次锁住class A >>>>");
            lock.lock();
            try {
                System.out.println("锁住class A--> 成功");
            } finally {
                System.out.println("释放第二次锁住的class A");
            }
        } finally {
            lock.unlock();
            System.out.println("释放第一次锁住的Class A对象");
        }
    }
}

运行结果

准备锁住class A >>>>
锁住class A--> 成功
准备再次锁住class A >>>>
锁住class A--> 成功
释放第二次锁住的class A
释放第一次锁住的Class A对象

如何保证可重入

当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要再测试一下Mark Word中偏向锁标志是否设置成1:没有则CAS竞争;设置了,则CAS将对象头偏向锁指向当前线程。再维护一个计数器,同个线程进入则自增1,离开再减1,直到为0才能释放。

到此这篇关于Java可重入锁的实现示例的文章就介绍到这了,更多相关Java可重入锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis plus自动生成代码tinyint(1)自动转换为Boolean的问题及解决

    mybatis plus自动生成代码tinyint(1)自动转换为Boolean的问题及解决

    这篇文章主要介绍了mybatis plus自动生成代码tinyint(1)自动转换为Boolean的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • SpringBoot整合DeepSeek实现AI对话功能

    SpringBoot整合DeepSeek实现AI对话功能

    本文介绍了如何在SpringBoot项目中整合DeepSeek API和本地私有化部署DeepSeekR1模型,通过SpringAI框架简化了人工智能模型的集成,感兴趣的小伙伴跟着小编一起来看看吧
    2025-02-02
  • 基于HttpServletRequest 相关常用方法的应用

    基于HttpServletRequest 相关常用方法的应用

    本篇文章小编为大家介绍,基于HttpServletRequest 相关常用方法的应用,需要的朋友参考下
    2013-04-04
  • Spring Boot应用事件监听示例详解

    Spring Boot应用事件监听示例详解

    这篇文章主要给大家介绍了关于Spring Boot应用事件监听的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • Java中防止数据重复提交超简单的6种方法

    Java中防止数据重复提交超简单的6种方法

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,这篇文章主要给大家介绍了关于Java中防止数据重复提交超简单的6种方法,需要的朋友可以参考下
    2021-11-11
  • Java调用SQL脚本执行常用的方法示例

    Java调用SQL脚本执行常用的方法示例

    这篇文章主要给大家介绍了关于Java调用SQL脚本执行常用的方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04
  • Java中 ? extends T 和 ? super T的理解

    Java中 ? extends T 和 ? super&nb

    本文主要介绍了Java中 ? extends T 和 ? super T的理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • 学习Java之如何正确地向上转型与向下转型

    学习Java之如何正确地向上转型与向下转型

    面向对象的第三个特征是多态,实现多态有三个必要条件:继承、方法重写和向上转型,在学习多态之前,我们还要先学习Java的类型转换,本篇文章就来带大家认识什么是类型转换,看看类型转换都有哪几种情况,以及如何避免类型转换时出现异常
    2023-05-05
  • Win10安装Maven与环境变量配置过程

    Win10安装Maven与环境变量配置过程

    本文介绍Maven的安装与配置方法,涵盖下载、环境变量设置、本地仓库及镜像配置,指导如何在IDEA中正确配置Maven,适用于Java及其他语言项目的构建与依赖管理
    2025-08-08
  • Java之Class.forName()用法案例详解

    Java之Class.forName()用法案例详解

    这篇文章主要介绍了Java之Class.forName()用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09

最新评论