应缩小synchronized同步粒度,仅锁定真正互斥的临界区;使用private final Object作为锁对象,避免this或类对象;同步块内只包含共享变量的最小读写操作,移出IO、计算等耗时逻辑;注意多锁死锁风险,优先用volatile、原子类替代锁以提升并发性能。

在代码块中使用 synchronized 关键字缩小同步粒度,核心是只对真正需要互斥访问的临界区加锁,避免锁住整个方法或无关逻辑,从而提升并发性能。
指定明确的锁对象,避免用 this 或类对象
同步代码块需显式传入一个锁对象。优先使用私有、final 的对象作为锁,防止外部干扰或锁升级:
- 不要写
synchronized(this) { ... }—— 容易被其他代码意外持锁,破坏封装性 - 推荐写法:
private final Object lock = new Object();,然后synchronized(lock) { ... } - 若锁的是某字段的状态(如缓存),可用该字段本身(确保非 null 且不被重新赋值)
只包裹读写共享状态的最小语句集
把锁严格限制在修改或依赖共享变量的几行代码内,其余计算、IO、日志等移出同步块:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 错误示例:在同步块里做 HTTP 请求、格式化字符串、遍历大集合
- 正确做法:先算好参数、拼好数据,再进同步块更新共享变量;更新完立刻释放锁,后续处理在块外进行
- 例如:缓存加载场景中,只同步“判断是否为空 + put 值”这两步,而不是整个 loadAndParse() 过程
避免嵌套锁和锁顺序不一致
缩小粒度后可能引入多个锁,需注意死锁风险:
- 若必须用多个锁,始终按固定顺序获取(如按对象哈希码排序后再锁)
- 尽量用
tryLock()(配合java.util.concurrent.locks.ReentrantLock)替代内置锁,便于超时控制和避免无限等待 - 同步块内不要再调用可能间接持锁的第三方方法,除非你完全清楚其同步行为
结合 volatile 或原子类进一步减小锁范围
不是所有共享访问都需要 synchronized:
- 简单状态标志(如 isRunning)、计数器,可改用
volatile或AtomicInteger,完全避开锁 - 若同步块里只做“读-改-写”,且逻辑简单,考虑用
AtomicReference.updateAndGet()等 CAS 操作替代 - 锁只是手段,目标是保证可见性与原子性——能用更轻量机制就不用重量级锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










