同步方法锁整个方法体、隐式锁对象、适合简单场景;同步块仅锁关键代码、显式可控锁对象、并发效率高且防死锁。二者底层均基于JVM monitor机制。

主要区别在锁的范围、锁对象控制力和实际并发效率。
锁的作用范围不同
修饰普通方法时,整个方法体都被锁定,从进入方法开始到返回结束,锁一直持有。哪怕只有两行代码操作共享变量,其余日志、计算、IO 等无关逻辑也得排队等待。
同步块只包裹真正需要互斥的代码,比如对 HashMap 的 put 或 remove 操作。前后非共享资源处理可并发执行,吞吐量明显更高。
锁对象是否可控
同步方法的锁对象是隐式的:
立即学习“Java免费学习笔记(深入)”;
- 实例方法 → 锁 this(当前对象)
- 静态方法 → 锁 MyClass.class
同步块允许显式指定任意非空对象作为锁:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 推荐用私有 final 对象:private final Object lock = new Object();
- 也可用具体资源对象,如 synchronized(map),实现资源粒度控制
- 避免用 this 或 getClass() 做同步块锁,防止子类或外部干扰引发意外竞争
性能与适用场景差异明显
方法级同步适合简单场景,比如封装单个字段的 getter/setter,逻辑短、状态单一。
同步块更适合真实业务:一个方法里可能含网络调用、本地计算、数据库查询,仅中间几行修改共享集合——只锁这几行,就能避免“假竞争”。
同步块还更利于规避死锁,支持按固定顺序获取多个锁,或结合 ReentrantLock 的 tryLock 实现超时与中断。
底层机制其实一样
无论是同步方法还是同步块,底层都依赖 JVM 的 monitor 机制,不是两种锁。关键差异全在于开发者如何界定临界区、选择锁目标、控制持有时间。
不要因为写法简洁就滥用同步方法,尤其当方法变长、职责增多时;同步块不是更复杂,而是更务实——它逼你回答两个问题:哪段代码真需要互斥?谁该持有这把锁?

















