优化线程竞争的关键是降低争用强度与缩短临界区:缩小同步范围、避免同步块内耗时操作、优先使用并发容器和原子类、合理选择锁粒度及JVM锁优化机制。

避免线程竞争带来的性能损耗,关键不是“消灭竞争”,而是让竞争更轻、更少、更可控。synchronized 本身是安全的,但高竞争会触发锁升级、阻塞、上下文切换等开销。优化的核心在于降低锁的争用强度和缩短临界区执行时间。
缩小同步范围,只锁真正共享的部分
把整个方法加 synchronized 往往过度了。多数情况下,只需保护几行修改共享状态的代码。
- 用同步代码块替代同步方法,明确指定锁对象和临界区边界
- 避免在同步块内做耗时操作(如 I/O、网络调用、复杂计算),可先取值、再同步、后处理
- 优先使用局部变量或不可变对象,减少对共享字段的依赖
选择更合适的锁粒度与结构
一把大锁守整块资源,容易成为瓶颈;分而治之能显著缓解争抢。
- 对集合类,优先用 ConcurrentHashMap、CopyOnWriteArrayList 等并发容器,它们内部已做分段或写时复制优化
- 若需自定义锁,可按业务维度拆分(如按用户 ID 取模分组),为不同子集分配独立锁对象
- 避免用 String、Integer 等常量或装箱类型作锁对象,防止意外的锁混用
利用 JVM 锁优化机制,适配运行时场景
JVM 不是简单地“上锁”,而是根据实际竞争动态选择最轻量的方式:偏向锁 → 轻量级锁 → 重量级锁。
立即学习“Java免费学习笔记(深入)”;
- 偏向锁在单线程反复进入时几乎零开销,适合读多、写少且访问集中于某一线程的场景(如 Web 请求中每个 Session 对应的本地状态)
- 若应用明显存在多线程交替竞争(如高频定时任务+用户请求混合),可考虑关闭偏向锁(-XX:-UseBiasedLocking),避免撤销开销
- 逃逸分析可能触发锁消除——如果编译器确认某个 synchronized 块内的对象不会逃逸出当前线程,JIT 会直接移除锁
用更高效的替代方案替代粗粒度 synchronized
不是所有同步都必须靠 synchronized。现代 Java 提供了更细粒度、更低开销的选择。
- 计数类场景优先用 AtomicInteger、AtomicLong 等原子类,底层基于 CAS,无锁且高效
- 读远多于写的场景,用 ReentrantReadWriteLock 或 StampedLock,允许多个读线程并发
- 需要等待/通知协作时,优先考虑 Condition 配合 ReentrantLock,比 wait/notify 更灵活可控



















