细粒度锁的核心是仅锁定真正需要保护的临界区,使用专用私有锁对象并按数据维度分段加锁,确保原子性不被破坏。

用同步代码块替代方法级锁
细粒度锁的核心是只锁定真正需要保护的临界区,而不是整个方法。synchronized 修饰实例方法时会锁住整个 this 对象,容易造成不必要的等待;改用 synchronized(锁对象) 代码块,能把同步范围精准控制在共享变量读写那几行。
- 只包裹实际操作共享资源的语句,比如
count++或list.add(item) - 非关键逻辑(如日志、网络调用、参数校验)放在同步块外,避免拖慢整体响应
- 示例中
preProcess()和postProcess()不参与同步,提升并发吞吐
创建专用锁对象,避免锁竞争扩散
不要直接用 this 或 ClassName.class 作锁,它们可能被类中其他无关方法共用,导致“锁污染”。声明一个私有 final 对象作为专属锁,把同步影响限制在最小作用域内。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 推荐写法:
private final Object lock = new Object(); - 错误做法:在多个不相关方法里都
synchronized(this),一个方法阻塞会让其他方法也排队 - 专用锁让不同业务逻辑各自独立加锁,互不影响
按数据维度拆分锁对象
当共享资源是集合或映射结构时,可进一步细化——不是一把锁管全部,而是为不同键或不同区域分配不同锁对象。例如对 Map<string list>></string>,按 key 的哈希值取模生成锁数组,实现“分段锁”效果。
- 适用场景:高并发读写不同 key 的缓存、用户会话管理、订单分片处理
- 注意点:锁对象必须稳定复用(不能每次 new),且要防止锁数量过多导致内存压力
- 本质是用空间换时间,降低单个锁的争用频率
确保临界区逻辑完整且无遗漏
细粒度不等于随意切分。如果一段业务逻辑天然具备原子性要求(比如先查后改、检查再更新),即使只涉及两行代码,也不能拆开加锁,否则会破坏一致性。
- 典型反例:把
if (count 拆成两个同步块,中间窗口期可能被其他线程插入 - 正确做法:整个判断+修改放进同一个
synchronized(lock)块中 - 细粒度的前提是语义正确,宁可稍宽一点,也不能漏掉关键步骤
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










