Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

  • JVM

    • JVM概述
    • JVM基础

    • 类加载机制

    • 运行时内存

    • 垃圾回收

    • 执行引擎与优化

      • 解释执行与JIT编译
      • 热点代码与编译优化
      • 逃逸分析与标量替换
      • 锁优化
        • 1. synchronized 的基本语义
        • 2. 锁状态
        • 3. 轻量级锁
        • 4. 重量级锁
        • 5. 锁消除
        • 6. 锁粗化
        • 7. 工程实践
        • 8. 阶段小结
        • 9. 锁状态变化图
        • 10. 锁竞争排查
        • 11. 工程优化方向
        • 12. Tips 快问快答
      • 类数据共享CDS与启动优化
    • 工具与问题排查

    • 调优实践与面试

目录

锁优化

Java 中 synchronized 的性能已经经过长期优化。现代 JVM 会根据运行时情况对锁进行多种优化,减少无竞争或低竞争场景下的开销。

# 1. synchronized 的基本语义

synchronized 保证:

  • 互斥。
  • 可见性。
  • 有序性。
synchronized (lock) {
    // critical section
}

进入同步块需要获取监视器锁,退出同步块释放锁。

# 2. 锁状态

HotSpot 对对象锁做了多种状态优化。

常见锁状态可以理解为:

  • 无锁。
  • 偏向锁。
  • 轻量级锁。
  • 重量级锁。

需要注意:偏向锁在 JDK 15 中已经默认禁用,并废弃了相关命令行参数,学习时理解历史演进即可。现代实践中更关注轻量级锁、重量级锁和锁消除等优化。

# 3. 轻量级锁

轻量级锁适合线程交替进入同步块、竞争不激烈的场景。

它尝试通过 CAS 避免直接进入操作系统互斥量,减少内核态切换开销。

如果竞争加剧,轻量级锁可能膨胀为重量级锁。

# 4. 重量级锁

重量级锁会涉及操作系统互斥量,竞争失败的线程可能被阻塞和唤醒。

这会带来:

  • 上下文切换。
  • 内核态开销。
  • 调度延迟。

高竞争同步块可能严重影响性能。

# 5. 锁消除

如果逃逸分析发现某个锁对象不会被其他线程访问,JIT 可以消除这个锁。

public void method() {
    Object lock = new Object();
    synchronized (lock) {
        // no escape
    }
}

这种锁没有实际同步意义。

# 6. 锁粗化

如果 JVM 发现一系列连续操作反复加锁解锁,可能把多个锁操作合并成一个更大范围的锁。

for (int i = 0; i < 100; i++) {
    synchronized (lock) {
        doSomething(i);
    }
}

锁粗化可以减少频繁加锁解锁开销,但也可能扩大锁持有时间。JVM 会根据优化策略决定。

# 7. 工程实践

写并发代码时,不要过度依赖 JVM 自动优化。更重要的是:

  • 缩小临界区。
  • 避免锁内执行 IO。
  • 避免锁内调用外部服务。
  • 减少热点锁竞争。
  • 合理使用并发容器。
  • 必要时拆分锁或使用无锁结构。

# 8. 阶段小结

JVM 对锁做了很多优化,使 synchronized 在无竞争和低竞争下性能较好。但高竞争锁仍然会成为瓶颈。锁优化知识帮助我们理解 JVM 行为,工程上仍要从设计上减少共享和竞争。

# 9. 锁状态变化图

无锁
  │
  ├─ 低竞争
  ▼
轻量级锁
  │
  ├─ CAS 失败、竞争加剧
  ▼
重量级锁
  │
  └─ 线程阻塞和唤醒涉及操作系统

偏向锁是历史上的低竞争优化,JDK 15 起默认禁用并废弃相关参数。学习锁状态时要结合 JDK 版本。

# 10. 锁竞争排查

锁竞争可能表现为:

  • CPU 高。
  • 响应时间长。
  • 大量线程 BLOCKED。
  • JFR 中 Monitor Blocked 事件多。
  • 线程栈集中在某个 synchronized 块。

排查工具:

  • jstack 看 BLOCKED 线程。
  • JFR 看锁竞争事件。
  • async-profiler 看锁 profiling。
  • 应用指标看队列和线程池。

# 11. 工程优化方向

问题 优化方向
锁粒度太大 缩小临界区
锁内 IO 把 IO 移出锁
单锁热点 分段锁、拆分数据
读多写少 ReadWriteLock、CopyOnWrite、不可变对象
计数热点 LongAdder
共享状态复杂 消息队列、Actor、串行化处理

# 12. Tips 快问快答

Q:synchronized 一定慢吗?

A:不是。现代 JVM 对无竞争和低竞争场景优化很多,真正慢的是高竞争和锁内慢操作。

Q:锁消除由谁做?

A:JIT 基于逃逸分析判断锁对象是否可能被其他线程访问。

Q:锁粗化一定好吗?

A:不一定。它减少加解锁次数,但可能扩大锁持有时间。

Q:怎么判断锁竞争严重?

A:看线程栈 BLOCKED 数量、JFR 锁事件、RT 抖动和 CPU 使用情况。

上次更新: 2026/06/24, 16:03:01
逃逸分析与标量替换
类数据共享CDS与启动优化

← 逃逸分析与标量替换 类数据共享CDS与启动优化→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式