核心思路是让锁更轻、更短、更专:缩短持有时间(耗时操作移出同步块)、减小粒度(分段锁、分片锁、字段级锁)、按读写场景选锁类型(readwritelock/stampedlock)、锁分离(不同操作用不同锁)。

核心思路不是“去掉锁”,而是让锁更轻、更短、更专——锁本身不慢,争抢它才慢。
缩短锁持有时间
锁占着越久,别人等得越急。把耗时操作(如IO、计算、网络调用)挪到同步块外,只锁真正需要保护的共享状态更新部分。
- 避免给整个方法加 synchronized,改用代码块精准加锁
- 例如:先查缓存、校验参数、拼装数据,这些都不用锁;只在更新计数器或写入共享 map 的那一行加锁
- 实测表明,锁持有时间从 2ms 降到 0.5ms,吞吐量可提升近一倍
缩小锁的保护范围(减小粒度)
一把大锁管全部,就像全公司共用一个会议室;拆成多个小锁,相当于每人有自己的工位。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 用 ConcurrentHashMap 替代 Collections.synchronizedMap —— 它把哈希表分成 16 个 Segment(JDK8 后改为 Node 数组 + CAS + synchronized 单节点),不同 key 可并发写
- 对集合按业务维度分片,比如按用户 ID 取模分配到不同锁对象:
Object lock = locks[userId % locks.length] - 避免锁住整个对象实例,优先锁具体字段或独立的锁对象(如
private final Object countLock = new Object())
按读写场景选合适锁类型
读多写少是常态,独占锁会让所有读线程排队,太浪费。
- 用
ReentrantReadWriteLock:多个线程可同时读,写操作独占且阻塞所有读写 - 读操作用
readLock().lock(),写操作用writeLock().lock() - 若读操作极频繁、写极少,还可考虑
StampedLock的乐观读模式,避免加锁开销
分离不同操作的锁(锁分离)
如果两个操作逻辑上不冲突,就别让它们抢同一把锁。
- 像
LinkedBlockingQueue:put()和take()各自持有一把锁(putLock和takeLock),入队出队互不影响 - 自定义类中,可为“下单”和“查单”设计不同的锁对象,只要它们修改的字段不重叠
- 注意:锁分离的前提是操作之间无状态依赖,否则会引发一致性问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










