细粒度锁核心是只锁真正需保护的资源:用private final object专用锁对象,按资源维度拆分独立锁,同步代码块仅包裹共享变量操作,避免锁this或class,以减少竞争、提升吞吐并利于jvm锁优化。

用 synchronized 实现细粒度锁,核心是“只锁真正需要保护的资源”,而不是整个方法或对象。锁范围越小,线程竞争越少,吞吐量越高。
明确锁对象,避免锁住 this 或 class
锁对象决定竞争范围。用 this 或静态方法锁 Class,容易造成全局串行;换成专用锁对象,就能隔离不同业务逻辑。
- 不要写
public synchronized void update() { ... }(锁整个实例) - 改用私有锁对象:
private final Object stockLock = new Object(); - 只在操作库存时加锁:
synchronized(stockLock) { deductStock(); } - 用户积分更新、日志记录等其他操作可并行执行,互不阻塞
按资源维度拆分锁,支持并发访问
如果多个数据项彼此独立(比如不同商品的库存),就别共用一把锁,而应为每个资源分配独立锁。
- 例如:用
ConcurrentHashMap<string object></string>存储商品 ID 对应的锁对象 - 扣减商品 A 库存:
synchronized(inventoryLocks.computeIfAbsent("A", k -> new Object())) { ... } - 扣减商品 B 库存:走另一把锁,完全不冲突
- 注意:锁对象不能是字符串字面量或 Integer 常量(存在复用风险),必须是 new 出来的对象
优先使用同步代码块,而非同步方法
同步方法隐式锁住整个方法体,哪怕前半段是无状态计算、后半段才操作共享变量,也会被拖慢。
- 把耗时的非共享操作(如参数校验、远程调用、JSON 解析)移出同步块
- 只包裹真正读写共享变量的几行代码
- 示例:先查数据库、再做本地缓存更新,只对缓存 map 的 put 操作加锁
结合锁升级特性,信任 JVM 自动优化
细粒度锁本身已降低竞争概率,JVM 更容易维持偏向锁或轻量级锁状态,避免进入重量级锁(线程挂起/唤醒开销大)。
- 单线程高频访问某个锁对象 → 偏向锁生效,几乎零开销
- 偶尔两个线程争抢 → 轻量级锁自旋,不进内核态
- 只有高并发、持续争抢时才升级为重量级锁
- 所以细粒度 + 合理锁对象 = 更大概率停留在高效锁态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











