[java 锁 - 03 重入写法 ]

news/2025/10/26 17:12:36/文章来源:https://www.cnblogs.com/shiyuzhahan/p/19167036

可重入锁的核心是“同一线程可重复获取同一把锁”,Java 中 synchronizedReentrantLock 都是可重入锁,写法各有特点。下面分别两种锁的可重入用法示例,清晰展示“重复获取锁”的场景:

一、synchronized 可重入写法(隐式可重入,JVM 自动管理)

synchronized 天生支持可重入,同一线程在持有锁时,调用同一锁对象的其他同步方法/代码块,会自动重复获取锁(无需手动操作)。

示例:同步方法的可重入

public class SynchronizedReentrantDemo {// 锁对象(当前实例 this)public synchronized void methodA() {System.out.println("进入 methodA(已获取锁)");// 同一线程调用同一锁的 methodB(可重入)methodB();System.out.println("退出 methodA(释放部分锁计数)");}// 同一锁对象(this)的同步方法public synchronized void methodB() {System.out.println("进入 methodB(重复获取锁,锁计数+1)");// 还可以继续调用其他同步方法(如 methodC),依然可重入System.out.println("退出 methodB(锁计数-1)");}public static void main(String[] args) {SynchronizedReentrantDemo demo = new SynchronizedReentrantDemo();// 启动线程调用 methodAnew Thread(demo::methodA).start();}
}

执行结果

进入 methodA(已获取锁)
进入 methodB(重复获取锁,锁计数+1)
退出 methodB(锁计数-1)
退出 methodA(释放部分锁计数)

原理
JVM 会为 synchronized 锁维护一个“重入计数器”:

  • 线程首次获取锁时,计数器=1;
  • 同一线程再次获取同一锁时,计数器+1;
  • 线程退出同步块/方法时,计数器-1;
  • 当计数器=0 时,锁才真正释放,其他线程可获取。

示例:同步代码块的可重入

public class SynchronizedBlockReentrantDemo {private final Object lock = new Object(); // 自定义锁对象public void methodX() {synchronized (lock) { // 首次获取 lock 锁(计数器=1)System.out.println("进入 methodX(已获取锁)");methodY(); // 同一线程调用同一锁的 methodYSystem.out.println("退出 methodX(计数器-1)");}}public void methodY() {synchronized (lock) { // 重复获取 lock 锁(计数器=2)System.out.println("进入 methodY(锁计数器+1)");System.out.println("退出 methodY(计数器-1)");}}public static void main(String[] args) {new Thread(new SynchronizedBlockReentrantDemo()::methodX).start();}
}

执行结果

进入 methodX(已获取锁)
进入 methodY(锁计数器+1)
退出 methodY(计数器-1)
退出 methodX(计数器-1)

二、ReentrantLock 可重入写法(显式可重入,手动控制)

ReentrantLock 是显式可重入锁,需手动调用 lock() 获取锁、unlock() 释放锁,重入时同样会增加计数器,释放时需对应减少计数器(lock()unlock() 次数必须相等)。

示例:

import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockDemo {private final ReentrantLock lock = new ReentrantLock(); // 可重入锁public void method1() {lock.lock(); // 首次获取锁(计数器=1)try {System.out.println("进入 method1(已获取锁)");method2(); // 同一线程调用 method2,重复获取锁} finally {lock.unlock(); // 释放一次(计数器=0,锁真正释放)System.out.println("退出 method1(释放锁)");}}public void method2() {lock.lock(); // 重复获取锁(计数器=2)try {System.out.println("进入 method2(锁计数器+1)");} finally {lock.unlock(); // 释放一次(计数器=1)System.out.println("退出 method2(释放部分锁)");}}public static void main(String[] args) {new Thread(new ReentrantLockDemo()::method1).start();}
}

执行结果

进入 method1(已获取锁)
进入 method2(锁计数器+1)
退出 method2(释放部分锁)
退出 method1(释放锁)

关键注意
ReentrantLocklock()unlock() 必须成对出现,重入几次就要释放几次,否则会导致锁无法真正释放(比如重入2次但只释放1次,计数器=1,其他线程永远无法获取锁)。

三、可重入锁的核心价值

避免“线程自我阻塞”:如果锁不可重入,同一线程在 methodA 中获取锁后,调用 methodB 时会因再次请求同一锁而阻塞(自己等自己),导致死锁。可重入锁通过计数器机制解决了这一问题,确保同一线程能流畅执行嵌套的同步逻辑(如事务嵌套、递归加锁等场景)。

总结

  • synchronized:隐式可重入,无需手动管理计数器,适合简单场景。
  • ReentrantLock:显式可重入,需手动控制 lock()/unlock() 次数,适合需要公平锁、超时等高级特性的场景。
    两种锁的可重入性都依赖“计数器”机制,核心是“同一线程重复获取锁时不阻塞,释放对应次数后才真正释放锁”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/946867.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年包装机厂家权威推荐榜:自动包装机,半自动包装机,高效包装设备源头厂家精选与选购指南

2025年包装机厂家权威推荐榜:自动包装机,半自动包装机,高效包装设备源头厂家精选与选购指南 随着制造业智能化转型的深入推进,包装机械行业正迎来技术革新的关键时期。自动包装机和半自动包装机作为生产线的重要环…

实用指南:Golang 中的字符串:常见错误和最佳实践

实用指南:Golang 中的字符串:常见错误和最佳实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

2025年自动上料机厂家推荐排行榜:螺旋上料机,真空上料机,粉末上料机,颗粒上料机专业制造商精选指南

2025年自动上料机厂家推荐排行榜:螺旋上料机,真空上料机,粉末上料机,颗粒上料机专业制造商精选指南 随着工业自动化进程的加速推进,自动上料机作为生产线上的关键设备,其技术水平和性能表现直接影响着生产效率和…

完整教程:iOS 抓包工具有哪些?实战对比、场景分工与开发者排查流程

完整教程:iOS 抓包工具有哪些?实战对比、场景分工与开发者排查流程2025-10-26 17:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto …

OI 笑传 #22

Hitsuzetsu技巧场,题目都不难。 1给定字符串 \(S\) 和许多人名字的缩写字符串 \(T\),判断是否存在一个分割点 \(p\)(\(1 \leq p < |S|\)),使得:子串 \(S[1..p]\) 可划分成若干“拼音”(至少两个小写英文字母…

2025长沙1024程序员日:为开发者职业发展插上腾飞之翼

2025长沙1024程序员日:为开发者职业发展插上腾飞之翼2025长沙1024程序员日:为开发者职业发展插上腾飞之翼 开发者目前最关注的是什么? 相信大多数人的答案是:AI来了,我的工作怎么办? 8月份,斯坦福发布的《关于A…

20232315 2025-2026-1 《网络与系统攻防技术》实验三实验报告

20232315 2025-2026-1 《网络与系统攻防技术》实验三实验报告20232315 2025-2026-1 《网络与系统攻防技术》实验三实验报告 目录一、实验基本信息二、实验内容三、实验要求四、实验过程4.1 正确使用msf编码器,使用msf…

2067C cf1500

题目描述: C. 九进制问题 时间限制:每个测试2秒 内存限制:每个测试256兆字节 给定一个正整数 n。每次操作中,你可以给 n 加上任意一个十进制表示仅由数字 9 组成的正整数(数字 9 可以重复出现多次)。 请问至少需…

兼职日志-mysqlpython出图

背景 1、win安装mysql 安装包https://downloads.mysql.com/archives/installer/ 安装步骤https://blog.csdn.net/mumiandeci/article/details/134520684 数据库连接工具https://www.hexhub.cn/CREATE DATABASE IF NOT …

2025东莞包装机/自动包装机/半自动包装机厂家推荐垚林机械,精准高效耐用!

当前包装设备领域的技术挑战与突破包装机械行业正面临着前所未有的技术革新压力。随着制造业智能化转型的加速,传统包装设备在精度、效率和稳定性方面暴露出诸多问题。据统计,目前仍有超过35%的制造企业因包装环节的…

使用pyautogui完成简单的游戏功能--皇室战争降杯

背景简介 有时候我们需要进行游戏的简单完成日常任务,例如皇室战争这个手机游戏,这种卡牌游戏很吃卡牌等级,由于我是国际服新号,等级不太高,不想打到太高分数,避免碰到高等级高卡牌高强度对手,但手动降低杯数太…

彻底清除浏览器缓存

代码如下: localStorage.clear(); sessionStorage.clear(); if (caches in window) {caches.keys().then(names => {names.forEach(name => caches.delete(name));console.log(Service Worker缓存已清除);}); }…

2025 年 10 月系统门窗厂商榜单揭晓,专业工艺制造与品牌保障口碑优选

2025 年 10 月系统门窗厂商榜单由建筑金属结构协会、家具装饰业商会联合发布,此次评选聚焦系统门窗 “工艺精细化、保障全周期” 核心要求,以《铝合金门窗》(GB/T 8478-2008)及《系统门窗技术要求》为双重技术基准…

2025自动上料机厂家推荐东莞市垚林机械,高效输送精准控料!

2025自动上料机厂家推荐东莞市垚林机械,高效输送精准控料! 在现代工业生产中,自动上料机作为自动化生产线的重要组成部分,其性能直接关系到生产效率和产品质量。随着工业4.0时代的深入发展,自动上料技术面临着新的…

Marchenko imaging-Kees Wapenaar-2014

目录Traditionally, the Marchenko equation forms a basis for 1D inverse scattering problems.什么是一维逆散射问题?Marchenko方程是什么?Marchenko方程解释 Traditionally, the Marchenko equation forms a bas…

ai-ti

重载(Overload)和重写(Override)是面向对象编程中两个重要的概念,都与方法相关,但适用场景和规则截然不同。 1. 重载(Overload):同一类中,方法名相同,参数不同 定义:在同一个类中,允许存在多个同名方法,…

实用指南:MySQL进阶知识点(八)---- SQL优化

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年 10 月系统门窗厂商榜单揭晓,专业系统智造与品牌保障口碑优选

2025 年 10 月系统门窗厂商榜单由中国建筑金属结构协会、全国工商联家具装饰业商会联合发布,此次评选聚焦系统门窗 “集成化、标准化、适配性” 核心特性,以《铝合金门窗》(GB/T 8478-2008)及《系统门窗技术要求》…

MX-S 10-25 比赛总结

比赛链接 好消息:永康喵喵这回没翻车,没有爆零或挂分! 坏消息:T2 这道唐题竟然没看懂题意,相当于不知道怎么踩油门! T1 一道非常简单的贪心。虽然现在看来十分简单,但是在场上想了好多种假的做法,毕竟贪心这种…

7天阅读betaflight

main就做初始化和 scheduler() 分配任务。 前情提要:common_pre.h、target.h 、common_post.h 三者的关系:feature配置都在里面了喵 ┌──────────────────┐ │ common_pre.h │ 全局默认配置…