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,只是计数器加减
释放规则 加锁多少次,必须释放多少次
相关推荐
程序员晓琪29 分钟前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly35 分钟前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨1 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜1 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端
阳火锅2 小时前
😭测试小姐姐终于不骂我了!这个提BUG神器太香了...
前端·javascript·面试
林希_Rachel_傻希希4 小时前
js里面的proxy理解。以及vue3响应式数据设计底层
前端·javascript·面试
SimonKing8 小时前
艹,维护AI写的代码,我心态崩了......
java·后端·程序员
用户1563068103518 小时前
Day01 | 什么是Agent?
面试
用户298698530148 小时前
Java Word 文档样式进阶:段落与文本背景色设置完全指南
java·后端
写代码的皮筏艇8 小时前
React中的forwardRef
前端·react.js·面试