好的,我们将分两课时详细讲解 synchronized 关键字,内容结构清晰,由浅入深。
第一课时:基础概念与使用
1. 核心作用
synchronized 是 Java 中用于实现线程同步的关键字,主要解决多线程环境下的数据竞争问题。它能确保:
- 原子性:操作不可分割
- 可见性:线程修改后的状态对其他线程立即可见
- 有序性:禁止指令重排序优化
2. 基本语法
// 1. 修饰实例方法 → 锁定当前对象实例
public synchronized void methodA() { … }
// 2. 修饰静态方法 → 锁定类的 Class 对象
public static synchronized void methodB() { … }
// 3. 同步代码块 → 显式指定锁对象
public void methodC() {
synchronized (lockObj) { // lockObj 可以是任意对象
// 临界区代码
}
}
3. 锁对象原理
每个 Java 对象都有一个内置锁(Monitor),当线程进入 synchronized 区域时:
4. 典型示例:线程安全计数器
class Counter {
private int count = 0;
public synchronized void increment() {
count++; // 非原子操作 → 需同步
}
}
第二课时:底层原理与优化
1. 字节码层面
通过 javap -c 查看编译后的字节码:
public void syncMethod();
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter // 获取锁
4: aload_1
5: monitorexit // 释放锁
6: return
https://weibo.com/tv/show/1034:5274388828979223
https://weibo.com/tv/show/1034:5274388753481738
https://weibo.com/tv/show/1034:5274388681916430
https://weibo.com/tv/show/1034:5274388619264003
https://weibo.com/tv/show/1034:5274388564738052
2. JVM 锁实现(Monitor 机制)
-
对象头结构
对象头包含 Mark Word,存储锁状态信息:| 锁状态 | 存储内容 |
|———-|———————–|
| 无锁 | 对象哈希码、GC 分代年龄 |
| 偏向锁 | 持有线程 ID |
| 轻量级锁 | 指向栈帧锁记录的指针 |
| 重量级锁 | 指向 Monitor 的指针 | -
Monitor 工作流程
graph LR
A[线程尝试进入同步区] –> B{锁是否被占用?}
B –>|否| C[获取锁并继续执行]
B –>|是| D[进入 ContentionList 等待]
D –> E[竞争升级]https://weibo.com/tv/show/1034:5274388828979223
https://weibo.com/tv/show/1034:5274388753481738
https://weibo.com/tv/show/1034:5274388681916430
https://weibo.com/tv/show/1034:5274388619264003
https://weibo.com/tv/show/1034:5274388564738052
3. 锁优化策略
- 偏向锁
适用于单线程重复访问,避免 CAS 开销 - 轻量级锁
通过自旋尝试获取锁,减少线程阻塞 - 锁粗化
合并相邻同步块,减少锁获取/释放次数 - 锁消除
JIT 编译时移除不可能竞争的锁(如局部对象)
4. 注意事项
- 避免锁嵌套导致死锁
- 同步代码块尽量粒度小
- 使用 java.util.concurrent 替代复杂场景
通过这两课时的学习,您将掌握 synchronized 从基础应用到 JVM 层实现的全貌。建议结合代码实践加深理解!



