synchronized锁粒度优化的核心是仅锁定真正需要互斥的临界区,剔除非共享操作;锁对象须私有final专用;按资源边界分锁,避免一把锁管全部;同步块内严禁耗时操作、外部调用及嵌套锁。

synchronized 锁粒度优化的核心,是让锁只覆盖真正需要互斥的代码,不拖泥带水、不越界、不共享。
只锁临界区,剔除所有非共享操作
同步块里只放读写共享变量的语句。日志打印、远程调用、JSON序列化、数据库查询、缓存刷新这些耗时或外部依赖操作,必须移出 synchronized 块。
- 余额校验可不加锁(只读且无状态竞争),扣减金额必须加锁(修改共享字段)
- 发短信通知、更新审计日志、记录监控指标——全在锁外执行
- 避免在同步块中调用可能阻塞、重入或回调的第三方方法
锁对象要私有、final、专用
锁对象不能是临时的、公共的或易变的,否则会破坏互斥语义。
- ✅ 推荐:private final Object lock = new Object();
- ✅ 特殊可用:Account account(该对象生命周期稳定、全局唯一、不被替换)
- ❌ 禁止:synchronized(this)(暴露锁,易被外部误用)、synchronized("key")(字符串常量池共享)、synchronized(new Object())(每次新建,锁无效)
按资源边界分锁,拒绝“一把锁管全部”
多个独立共享资源,就该配多把锁。用户A和用户B的操作不应互相阻塞。
- 按 userId 分锁:用 ConcurrentHashMap
缓存每个用户的专属锁对象 - 按商品 ID 分锁:库存扣减按 itemId 隔离,不同商品互不影响
- 注意强耦合字段:balance 和 frozenBalance 必须原子变更 → 仍需共用同一把锁,拆锁会破坏一致性
规避嵌套与外部调用,防锁拖长和死锁
同步块内调用未知方法,等于把锁的控制权交出去,风险极高。
- 禁止在 synchronized 块中调用 sendEmail()、httpClient.post()、service.update() 等外部服务
- 多锁场景必须严格约定获取顺序:例如“先锁账户,再锁交易流水”,避免循环等待
- 若需组合操作,优先考虑拆成“读→计算→写”三段,仅“写”阶段加锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











