最有效提升多线程性能的手段是缩小synchronized代码块范围,仅包裹真正共享且需互斥的临界区,剥离日志、远程调用等无关操作,并采用专用私有锁对象、按业务维度分拆锁粒度,同时警惕隐式锁扩大与死锁。

直接缩小 synchronized 代码块的范围,是提升多线程性能最有效、最可控的手段之一。核心不是“少写几行”,而是精准识别并只锁定真正共享、必须互斥的那部分操作。
只包裹临界区,剥离无关逻辑
临界区 = 多个线程同时读写同一份共享变量的最小语句集合。其余所有操作——日志、远程调用、计算、对象创建、非共享字段访问——都必须移出 synchronized 块。
- ❌ 错误:在同步块里查数据库、发邮件、拼接字符串
- ✅ 正确:先完成耗时操作,再用极短的同步块更新 balance 或 status 等关键字段
用专用私有锁对象,避免锁污染
锁对象必须稳定、唯一、不对外暴露。this 或 Class 容易被意外使用,导致不同业务逻辑互相阻塞。
- ✅ 推荐:private final Object lock = new Object(); —— 专锁本类关键资源
- ✅ 若操作聚焦于某个实体(如 Account a),可用 a 作锁,但前提是 a 在整个生命周期中不被替换
- ❌ 避免:new Object()(每次新建,锁失效)、String 字面量(常量池共享,跨类意外串锁)、Integer.valueOf(1)(缓存值复用)
按业务维度拆分锁粒度
全局一把锁是性能瓶颈的根源。把“锁整个类”变成“锁具体业务单元”,并发能力立刻提升。
- 用户操作 → 按 userId 构建锁:ConcurrentMap
userLocks 缓存每个用户的专属锁 - 商品库存 → 按 itemId 加锁,不同商品扣减完全不干扰
- 计数器类场景 → 直接用 AtomicInteger 替代 synchronized,零锁开销
警惕隐式锁扩大和死锁风险
同步块内调用外部方法,可能引入不可控的锁依赖,延长持锁时间甚至引发死锁。
- 不要在 synchronized 块里调用第三方 SDK、RPC 方法或未审查的工具类
- 避免嵌套 synchronized(this) 和 synchronized(Other.class),尤其当调用链不清晰时
- 若必须调用其他同步方法,确认其锁对象与当前一致,且设计为可重入(synchronized 本身支持,但需逻辑合理)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











