《synchronized 到底锁了谁?底层原理、可重入、锁升级,一次给你讲明白》
一、开头先说人话
兄弟们,synchronized 这东西,初学者看它像保安,面试官看它像祖传考点,项目里看它又像个老实巴交但关键时刻真能顶的哥们。
它干的事其实特别朴素:
同一时刻,只让一个线程进来干活。
就像烧烤摊只有一把秘制刷子,谁先拿到谁先刷,别的兄弟先排队,别都挤上来把羊肉刷成拖把。
二、synchronized 的底层原理是什么?
底层核心就一个词:monitor(监视器)。
你可以把 monitor 理解成对象门口的门禁。线程想进同步代码块,先刷门禁;刷成功就进去,刷不成功就等着。
要注意一个细节:
- 同步代码块,字节码里通常会看到 monitorenter 和 monitorexit
- 同步方法,不一定直接编译成这两个指令,它更多是依赖方法的 ACC_SYNCHRONIZED 标志,由 JVM 在调用和返回时隐式加锁、释放锁
图 1:synchronized 底层执行流程

一句话翻译:
synchronized 不是给代码上锁,而是线程去竞争“某个对象关联的监视器”。
三、synchronized 锁的到底是什么?
这块特别容易被问,也特别容易答成“锁代码”。
不对,锁的不是代码,锁的是对象。
具体分 3 种:
- 修饰普通方法:锁的是当前对象,也就是 this
- 修饰静态方法:锁的是当前类对应的 Class 对象
- 修饰同步代码块:锁的是你括号里写的那个对象
图 2:三种锁对象方式

所以别再说“这个 synchronized 锁住了这几行代码”。
更准确的说法应该是:
这几行代码执行前,线程先去抢某个对象的 monitor。
四、什么是可重入锁?
可重入,说白了就是:
同一个线程已经拿到这把锁了,再进一次,不会把自己堵死。
这很像你已经是烧烤摊老板了,进后厨不用再跟自己打申请。
不然你刚进厨房,又得敲门问“老板我能不能进”,结果老板就是你自己,那就很尴尬了。
一个最小代码例子
public class SyncDemo {
private int count = 0;
public synchronized void add() {
print(); // 我已经拿到 this 的锁了,再进一次也没事,这就叫可重入
count++;
System.out.println("count = " + count);
}
private synchronized void print() {
System.out.println(Thread.currentThread().getName() + " 正在干活");
}
public static void main(String[] args) {
SyncDemo demo = new SyncDemo();
new Thread(demo::add, "t1").start();
}
}
这段代码能正常跑,不会把自己锁死,就是因为 synchronized 是可重入锁。
图 3:可重入的意思

五、synchronized 和 ReentrantLock 有什么区别?
这俩都能加锁,也都可重入,但性格不一样。

如果你只是普通同步场景,synchronized 就够用了,简单、省心、不容易忘记解锁。
如果你需要这些高级玩法:
- 公平锁
- 可中断锁
- 超时获取锁
- 多条件队列
那就让 ReentrantLock 上场。
一句话总结:
日常开发大多数场景用 synchronized,复杂控制再上 ReentrantLock。
六、锁升级过程是什么?
这块是八股高频题,但也最容易背成旧版本说明书。
经典面试口径一般会说:
- 偏向锁
- 轻量级锁
- 重量级锁
意思是 JVM 会根据竞争激烈程度,尽量先用轻一点的方式搞定;竞争越来越激烈,再慢慢“膨胀”成更重的锁。
图 4:经典锁状态演进

但这里必须补一句版本说明,别把老知识背成永久真理:
在 HotSpot 里,偏向锁从 JDK 15 开始已经默认禁用并被弃用。
所以今天你再讲锁优化,更稳妥的表达是:
- synchronized 确实经历过多种锁优化设计
- “偏向锁 -> 轻量级锁 -> 重量级锁”是经典理解模型
- 但不同 JDK 版本实现细节并不完全一样,不能一把梭哈到所有版本
七、为什么以前总说 synchronized 很重,现在又说它没那么慢了?
因为早年它确实容易走到操作系统层面的互斥量,线程挂起、唤醒开销大,像你为了烤两串羊肉,专门把整条街交通都管制了,成本当然高。
后来 JVM 做了不少优化,比如:
- 更轻量的竞争路径
- 自旋等手段减少用户态/内核态切换
- 锁状态按竞争情况逐步升级
所以现在再说 synchronized,不能张嘴就是“它性能差”。
更靠谱的说法是:
它在低竞争或一般竞争场景下,已经没有当年那么笨重了;性能要看具体并发场景。
八、整篇文章你最该记住的 5 句话
- synchronized 的底层核心是 monitor
- 同步代码块常见 monitorenter / monitorexit,同步方法常见 ACC_SYNCHRONIZED
- 它锁的不是代码,而是对象的监视器
- 它是可重入锁
- 现代 JVM 对它做过很多优化,但锁实现细节会随 JDK 版本变化
一句话总结
synchronized 本质上就是线程去抢对象 monitor 的门禁系统,锁的是对象,支持可重入,JVM 还会根据竞争情况尽量把这把锁用得更聪明。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)