JAVA面试-并发篇 02-synchronized 锁可以重入吗

synchronized 可重入机制

一、一句话核心

同一个线程可以多次获取同一把锁,不会死锁。

  • 原理:锁自带计数器,加锁+1,释放-1,归0才真正释放
  • 类比:一把家门钥匙能开家里所有房间门

二、为什么必须有可重入?

没有可重入,下面代码会直接死锁:

java 复制代码
public synchronized void a() { b(); } // 拿了锁调用b()
public synchronized void b() {}       // 再拿同一把锁,自己等自己

三、三种锁的可重入实现对比

锁状态 计数器在哪 怎么判断是同一个线程
偏向锁 对象头Mark Word 检查里面存的线程ID
轻量级锁 线程栈的Lock Record链表 检查锁记录的所有者
重量级锁 Monitor对象的count字段 检查Monitor的owner

四、重量级锁(最常考)实现

Monitor核心结构

#mermaid-svg-yATmT3CQWVrdXhC0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yATmT3CQWVrdXhC0 .error-icon{fill:#552222;}#mermaid-svg-yATmT3CQWVrdXhC0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yATmT3CQWVrdXhC0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yATmT3CQWVrdXhC0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yATmT3CQWVrdXhC0 .marker.cross{stroke:#333333;}#mermaid-svg-yATmT3CQWVrdXhC0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yATmT3CQWVrdXhC0 p{margin:0;}#mermaid-svg-yATmT3CQWVrdXhC0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster-label text{fill:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster-label span{color:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster-label span p{background-color:transparent;}#mermaid-svg-yATmT3CQWVrdXhC0 .label text,#mermaid-svg-yATmT3CQWVrdXhC0 span{fill:#333;color:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 .node rect,#mermaid-svg-yATmT3CQWVrdXhC0 .node circle,#mermaid-svg-yATmT3CQWVrdXhC0 .node ellipse,#mermaid-svg-yATmT3CQWVrdXhC0 .node polygon,#mermaid-svg-yATmT3CQWVrdXhC0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yATmT3CQWVrdXhC0 .rough-node .label text,#mermaid-svg-yATmT3CQWVrdXhC0 .node .label text,#mermaid-svg-yATmT3CQWVrdXhC0 .image-shape .label,#mermaid-svg-yATmT3CQWVrdXhC0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-yATmT3CQWVrdXhC0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yATmT3CQWVrdXhC0 .rough-node .label,#mermaid-svg-yATmT3CQWVrdXhC0 .node .label,#mermaid-svg-yATmT3CQWVrdXhC0 .image-shape .label,#mermaid-svg-yATmT3CQWVrdXhC0 .icon-shape .label{text-align:center;}#mermaid-svg-yATmT3CQWVrdXhC0 .node.clickable{cursor:pointer;}#mermaid-svg-yATmT3CQWVrdXhC0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yATmT3CQWVrdXhC0 .arrowheadPath{fill:#333333;}#mermaid-svg-yATmT3CQWVrdXhC0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yATmT3CQWVrdXhC0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yATmT3CQWVrdXhC0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yATmT3CQWVrdXhC0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yATmT3CQWVrdXhC0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yATmT3CQWVrdXhC0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster text{fill:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 .cluster span{color:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yATmT3CQWVrdXhC0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yATmT3CQWVrdXhC0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-yATmT3CQWVrdXhC0 .icon-shape,#mermaid-svg-yATmT3CQWVrdXhC0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yATmT3CQWVrdXhC0 .icon-shape p,#mermaid-svg-yATmT3CQWVrdXhC0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yATmT3CQWVrdXhC0 .icon-shape .label rect,#mermaid-svg-yATmT3CQWVrdXhC0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yATmT3CQWVrdXhC0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yATmT3CQWVrdXhC0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yATmT3CQWVrdXhC0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Monitor
owner: 谁拿着锁
count: 重入次数

执行流程

#mermaid-svg-mIT6OWpTDkETMVtV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mIT6OWpTDkETMVtV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mIT6OWpTDkETMVtV .error-icon{fill:#552222;}#mermaid-svg-mIT6OWpTDkETMVtV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mIT6OWpTDkETMVtV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mIT6OWpTDkETMVtV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mIT6OWpTDkETMVtV .marker.cross{stroke:#333333;}#mermaid-svg-mIT6OWpTDkETMVtV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mIT6OWpTDkETMVtV p{margin:0;}#mermaid-svg-mIT6OWpTDkETMVtV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mIT6OWpTDkETMVtV .cluster-label text{fill:#333;}#mermaid-svg-mIT6OWpTDkETMVtV .cluster-label span{color:#333;}#mermaid-svg-mIT6OWpTDkETMVtV .cluster-label span p{background-color:transparent;}#mermaid-svg-mIT6OWpTDkETMVtV .label text,#mermaid-svg-mIT6OWpTDkETMVtV span{fill:#333;color:#333;}#mermaid-svg-mIT6OWpTDkETMVtV .node rect,#mermaid-svg-mIT6OWpTDkETMVtV .node circle,#mermaid-svg-mIT6OWpTDkETMVtV .node ellipse,#mermaid-svg-mIT6OWpTDkETMVtV .node polygon,#mermaid-svg-mIT6OWpTDkETMVtV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mIT6OWpTDkETMVtV .rough-node .label text,#mermaid-svg-mIT6OWpTDkETMVtV .node .label text,#mermaid-svg-mIT6OWpTDkETMVtV .image-shape .label,#mermaid-svg-mIT6OWpTDkETMVtV .icon-shape .label{text-anchor:middle;}#mermaid-svg-mIT6OWpTDkETMVtV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mIT6OWpTDkETMVtV .rough-node .label,#mermaid-svg-mIT6OWpTDkETMVtV .node .label,#mermaid-svg-mIT6OWpTDkETMVtV .image-shape .label,#mermaid-svg-mIT6OWpTDkETMVtV .icon-shape .label{text-align:center;}#mermaid-svg-mIT6OWpTDkETMVtV .node.clickable{cursor:pointer;}#mermaid-svg-mIT6OWpTDkETMVtV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mIT6OWpTDkETMVtV .arrowheadPath{fill:#333333;}#mermaid-svg-mIT6OWpTDkETMVtV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mIT6OWpTDkETMVtV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mIT6OWpTDkETMVtV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mIT6OWpTDkETMVtV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mIT6OWpTDkETMVtV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mIT6OWpTDkETMVtV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mIT6OWpTDkETMVtV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mIT6OWpTDkETMVtV .cluster text{fill:#333;}#mermaid-svg-mIT6OWpTDkETMVtV .cluster span{color:#333;}#mermaid-svg-mIT6OWpTDkETMVtV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mIT6OWpTDkETMVtV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mIT6OWpTDkETMVtV rect.text{fill:none;stroke-width:0;}#mermaid-svg-mIT6OWpTDkETMVtV .icon-shape,#mermaid-svg-mIT6OWpTDkETMVtV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mIT6OWpTDkETMVtV .icon-shape p,#mermaid-svg-mIT6OWpTDkETMVtV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mIT6OWpTDkETMVtV .icon-shape .label rect,#mermaid-svg-mIT6OWpTDkETMVtV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mIT6OWpTDkETMVtV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mIT6OWpTDkETMVtV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mIT6OWpTDkETMVtV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
否
是
否
线程拿锁
owner是自己?
count+1
owner是空?
owner=自己, count=1
排队等
执行代码
释放: count-1
count=0?
owner清空, 唤醒排队线程
锁还在自己手里

五、轻量级锁实现

用栈里多个锁记录代替计数器:
#mermaid-svg-vzizJt8FbeAbiz3q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vzizJt8FbeAbiz3q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vzizJt8FbeAbiz3q .error-icon{fill:#552222;}#mermaid-svg-vzizJt8FbeAbiz3q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vzizJt8FbeAbiz3q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vzizJt8FbeAbiz3q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vzizJt8FbeAbiz3q .marker.cross{stroke:#333333;}#mermaid-svg-vzizJt8FbeAbiz3q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vzizJt8FbeAbiz3q p{margin:0;}#mermaid-svg-vzizJt8FbeAbiz3q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vzizJt8FbeAbiz3q .cluster-label text{fill:#333;}#mermaid-svg-vzizJt8FbeAbiz3q .cluster-label span{color:#333;}#mermaid-svg-vzizJt8FbeAbiz3q .cluster-label span p{background-color:transparent;}#mermaid-svg-vzizJt8FbeAbiz3q .label text,#mermaid-svg-vzizJt8FbeAbiz3q span{fill:#333;color:#333;}#mermaid-svg-vzizJt8FbeAbiz3q .node rect,#mermaid-svg-vzizJt8FbeAbiz3q .node circle,#mermaid-svg-vzizJt8FbeAbiz3q .node ellipse,#mermaid-svg-vzizJt8FbeAbiz3q .node polygon,#mermaid-svg-vzizJt8FbeAbiz3q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vzizJt8FbeAbiz3q .rough-node .label text,#mermaid-svg-vzizJt8FbeAbiz3q .node .label text,#mermaid-svg-vzizJt8FbeAbiz3q .image-shape .label,#mermaid-svg-vzizJt8FbeAbiz3q .icon-shape .label{text-anchor:middle;}#mermaid-svg-vzizJt8FbeAbiz3q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vzizJt8FbeAbiz3q .rough-node .label,#mermaid-svg-vzizJt8FbeAbiz3q .node .label,#mermaid-svg-vzizJt8FbeAbiz3q .image-shape .label,#mermaid-svg-vzizJt8FbeAbiz3q .icon-shape .label{text-align:center;}#mermaid-svg-vzizJt8FbeAbiz3q .node.clickable{cursor:pointer;}#mermaid-svg-vzizJt8FbeAbiz3q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vzizJt8FbeAbiz3q .arrowheadPath{fill:#333333;}#mermaid-svg-vzizJt8FbeAbiz3q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vzizJt8FbeAbiz3q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vzizJt8FbeAbiz3q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vzizJt8FbeAbiz3q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vzizJt8FbeAbiz3q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vzizJt8FbeAbiz3q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vzizJt8FbeAbiz3q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vzizJt8FbeAbiz3q .cluster text{fill:#333;}#mermaid-svg-vzizJt8FbeAbiz3q .cluster span{color:#333;}#mermaid-svg-vzizJt8FbeAbiz3q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vzizJt8FbeAbiz3q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vzizJt8FbeAbiz3q rect.text{fill:none;stroke-width:0;}#mermaid-svg-vzizJt8FbeAbiz3q .icon-shape,#mermaid-svg-vzizJt8FbeAbiz3q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vzizJt8FbeAbiz3q .icon-shape p,#mermaid-svg-vzizJt8FbeAbiz3q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vzizJt8FbeAbiz3q .icon-shape .label rect,#mermaid-svg-vzizJt8FbeAbiz3q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vzizJt8FbeAbiz3q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vzizJt8FbeAbiz3q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vzizJt8FbeAbiz3q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 线程栈
锁记录3
锁记录2
锁记录1 ← 对象头指向这里

  • 重入1次,栈里多1个锁记录
  • 释放1次,栈里弹出1个锁记录
  • 全弹完,锁真正释放

六、常见误区

误区 正确结论
不同线程也能重入 只允许同一个线程
静态和普通方法能互相重入 锁的对象不同,不能
重入次数无限 最多2^31-1次,超了报错

七、关键总结

特性 说明
核心目的 避免自己把自己卡死
性能影响 几乎为0,只是计数器加减
释放规则 加锁多少次,必须释放多少次
相关推荐
金銀銅鐵25 分钟前
[Java] 用 CLI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
qq_4369621832 分钟前
金蝶云星空数据分析怎么做?
java·数据库·数据分析
代码山河32 分钟前
键盘输入与输出:Scanner与System.out详解
java·学习·架构·教程·面向对象·项目
碧海银沙音频科技研究院37 分钟前
基于炬芯ATS308X的BLE 无线方式离线日志传输导出功能实现
java·linux·服务器
denlaku1 小时前
JDK 20 新特性详解
java
木井巳1 小时前
【JavaEE】SpringBoot 统一功能处理: 拦截器、统一返回与全局异常
java·spring boot·后端·spring·java-ee
SL-staff1 小时前
JVS-Rules金融风控实践:四大原生能力的技术实现与可落地配置指南
java·决策树·规则引擎·函数计算·金融风控·jvs-rules·数据源抽象
考研保研资料分享1 小时前
2022旅游管理跨保华东师大人文地理:五场面试与择校复盘
面试·旅游
Thomas.Sir2 小时前
第6课:SpringBoot4.x 核心注解全解:Component、Bean、Scope、Lazy等IOC相关注解
java·spring boot
paopaokaka_luck2 小时前
美食推荐系统(协同过滤算法推荐、AI助手、HanLP中文分词、 ECharts可视化分析、菜谱学习与话题交流)
java·spring boot·mysql·tomcat·echarts