news 2026/2/6 13:43:34

Java中synchronized和ReentrantLock锁重入机制详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java中synchronized和ReentrantLock锁重入机制详解

在Java中,锁的重入(Reentrancy)是指同一个线程可以多次获取同一把锁而不会造成死锁的特性。这是Java内置锁(synchronized)和ReentrantLock的一个重要特性。

核心概念

当一个线程已经持有某个锁时,它可以再次请求获取这个锁,JVM会记录锁被同一个线程持有的次数,只有当锁完全释放(计数器归零)时,其他线程才能获取该锁。

synchronized的锁重入示例

publicclassReentrantDemo{publicsynchronizedvoidmethodA(){System.out.println("进入methodA");methodB();// 调用另一个同步方法System.out.println("离开methodA");}publicsynchronizedvoidmethodB(){System.out.println("进入methodB");// 做一些操作System.out.println("离开methodB");}publicstaticvoidmain(String[]args){ReentrantDemodemo=newReentrantDemo();// 同一个线程可以重入锁newThread(()->demo.methodA()).start();}}

输出:

进入methodA 进入methodB 离开methodB 离开methodA

ReentrantLock的锁重入示例

importjava.util.concurrent.locks.ReentrantLock;publicclassReentrantLockDemo{privatefinalReentrantLocklock=newReentrantLock();publicvoidouter(){lock.lock();try{System.out.println("外层方法,锁重入计数: "+lock.getHoldCount());inner();// 调用内层方法,重入锁}finally{lock.unlock();}}publicvoidinner(){lock.lock();try{System.out.println("内层方法,锁重入计数: "+lock.getHoldCount());}finally{lock.unlock();}}publicstaticvoidmain(String[]args){ReentrantLockDemodemo=newReentrantLockDemo();demo.outer();}}

输出:

外层方法,锁重入计数: 1 内层方法,锁重入计数: 2

锁重入的实现机制

1. synchronized的实现

  • JVM为每个锁对象维护一个计数器
  • 当线程第一次获取锁时,计数器=1
  • 每次重入,计数器+1
  • 每次退出同步代码块,计数器-1
  • 计数器归零时,锁完全释放

2. ReentrantLock的实现

  • 使用AQS(AbstractQueuedSynchronizer)的state字段记录重入次数
  • 通过getHoldCount()方法可以获取当前线程的重入次数

为什么需要锁重入?

1.避免死锁

// 如果没有锁重入,这段代码会导致死锁publicclassWithoutReentrancy{publicsynchronizedvoida(){b();// 调用另一个同步方法}publicsynchronizedvoidb(){// 一些操作}}

2.支持面向对象的设计

  • 子类可以重写父类的同步方法
  • 方法可以调用其他同步方法
  • 支持递归调用

锁重入的注意事项

1.释放次数必须匹配

publicclassLockReleaseExample{privatefinalReentrantLocklock=newReentrantLock();publicvoidwrong(){lock.lock();lock.lock();// 重入// 业务逻辑lock.unlock();// 只释放一次,锁没有完全释放!}publicvoidcorrect(){lock.lock();lock.lock();// 重入try{// 业务逻辑}finally{lock.unlock();// 释放一次lock.unlock();// 再释放一次}}}

2.可重入锁 vs 不可重入锁

特性可重入锁不可重入锁
同一线程多次获取允许会导致死锁
实现复杂度较高较低
使用场景大多数情况特定场景
Java示例synchronized, ReentrantLock需要自定义实现

实际应用场景

1.递归调用

publicclassRecursiveExample{publicsynchronizedvoidrecursive(intn){if(n<=0)return;System.out.println("递归深度: "+n);recursive(n-1);// 递归调用,需要锁重入}}

2.模板方法模式

publicabstractclassTemplateMethod{publicfinalvoidtemplateMethod(){synchronized(this){doOperation1();doOperation2();// 可能需要锁保护}}protectedabstractvoiddoOperation1();protectedabstractvoiddoOperation2();}

总结

锁重入是Java并发编程中的重要特性,它:

  1. 提高了灵活性:允许方法调用其他同步方法
  2. 避免了自死锁:同一个线程不会因为重复获取锁而阻塞自己
  3. 简化了编程:开发者不需要担心嵌套同步的问题
  4. 支持面向对象设计:便于继承和多态的实现

Java中的synchronized关键字和ReentrantLock都内置了锁重入机制,这也是为什么它们被称为"可重入锁"的原因。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/4 16:48:38

详解银狐远控源码中那些C++编码问题

特别申明&#xff1a; 本文内容仅限于用作技术交流&#xff0c;请勿使用本文介绍的技术做任何其他用途&#xff0c;否则后果自负&#xff0c;与本号无关。 原始的银狐远程控制软件中&#xff0c;存在大量C编码问题&#xff0c;大多数错误都属于低级错误。这些错误造成银狐远控…

作者头像 李华
网站建设 2026/2/5 4:17:35

入校申报审批系统的设计与实现毕业论文+PPT(附源代码+演示视频)

文章目录入校申报审批系统的设计与实现一、项目简介&#xff08;源代码在文末&#xff09;1.运行视频2.&#x1f680; 项目技术栈3.✅ 环境要求说明4.包含的文件列表&#xff08;含论文&#xff09;数据库结构与测试用例系统功能结构后端运行截图项目部署源码下载入校申报审批系…

作者头像 李华
网站建设 2026/1/30 22:58:30

有哪些好的服务器托管服务商推荐?—— 以尚航科技为核心的专业测评​

在数字化转型加速的背景下&#xff0c;服务器托管服务的选择直接关系到企业业务的稳定性、数据安全与长期运营成本。本文将以国内知名服务商尚航科技为主要案例&#xff0c;结合行业标准与公开数据&#xff0c;从基础设施、网络能力、安全合规、运维服务等维度进行客观测评&…

作者头像 李华
网站建设 2026/2/4 13:42:58

基于SpringBoot的宠物服务系统(源码+lw+部署文档+讲解等)

课题介绍本课题聚焦宠物服务全流程规范化对接与服务质量提升的核心需求&#xff0c;设计并实现基于SpringBoot框架的宠物服务系统。当前宠物服务领域存在服务资源分散、用户与服务商对接低效、服务流程不透明、服务记录难追溯等问题&#xff0c;制约了宠物服务行业的发展效率&a…

作者头像 李华
网站建设 2026/1/30 15:43:43

老年综合实训室建设指南:从规划到落地的全流程解析

随着社会老龄化进程的加速&#xff0c;面向老年服务人才的专业化、实践化培养变得日益重要。老年综合实训室作为集教学、实训、技能考核于一体的专业化场所&#xff0c;其科学建设成为相关院校和培训机构关注的重点。本文旨在提供一份从规划到落地的全流程解析&#xff0c;为有…

作者头像 李华