一、引言
synchronized 是 Java 并发编程中最基础且核心的同步机制,用于保证临界区代码的原子性、可见性和有序性。早期 synchronized 因性能开销较大被称为'重量级锁',但 JVM 通过偏向锁、轻量级锁、重量级锁的三级锁机制进行了深度优化,在不同并发场景下自动切换锁状态,平衡了线程安全与执行效率。本文基于 Java 并发编程核心知识,结合具体代码示例与 JVM 底层实现,详细拆解 synchronized 的优化原理与实践逻辑。
二、synchronized 核心基础
2.1 核心作用
- 互斥性:同一时刻仅允许一个线程进入临界区,避免竞态条件。
- 可见性:线程释放锁时,会将工作内存中修改的共享变量同步至主存;线程获取锁时,会清空工作内存中共享变量的缓存,从主存重新读取。
- 有序性:禁止指令重排,保证临界区代码按顺序执行。
2.2 底层依赖:Monitor 机制
synchronized 的同步语义依赖Java 对象头和Monitor(管程) 实现:
- Java 对象头结构:
- 普通对象的对象头包含 Mark Word(32 位 / 64 位)和 Klass Word(类指针)。
- Mark Word 是核心,存储对象的锁状态、哈希码、年龄代、偏向线程 ID 等信息,不同锁状态下结构不同。
- Monitor 原理:
- Monitor 是操作系统级别的同步原语,每个 Java 对象都关联一个 Monitor(通过对象头的 Mark Word 指向)。
- Monitor 包含 EntryList(等待锁的线程队列)、Owner(持有锁的线程)、WaitSet(调用 wait() 后等待的线程队列)。
- 线程获取锁时进入 EntryList 阻塞,获取锁后成为 Owner;释放锁时唤醒 EntryList 中的线程竞争锁。
2.3 基础使用代码示例
synchronized 可修饰实例方法、静态方法和代码块,以下是三种使用方式的核心示例:
public class SynchronizedBasicDemo {
// 1. 修饰实例方法(锁对象:当前实例 this)
public synchronized void instanceMethod() {
System.out.println("实例方法同步:" + Thread.currentThread().getName());
try {
Thread.sleep(100); // 模拟业务耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 2. 修饰静态方法(锁对象:SynchronizedBasicDemo.class)
public static synchronized void {
System.out.println( + Thread.currentThread().getName());
{
Thread.sleep();
} (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
();
{
(lock) {
System.out.println( + Thread.currentThread().getName());
}
() {
System.out.println( + Thread.currentThread().getName());
}
(SynchronizedBasicDemo.class) {
System.out.println( + Thread.currentThread().getName());
}
}
{
();
(demo::instanceMethod, ).start();
(demo::instanceMethod, ).start();
( ()::instanceMethod, ).start();
(SynchronizedBasicDemo::staticMethod, ).start();
(SynchronizedBasicDemo::staticMethod, ).start();
(demo::codeBlockMethod, ).start();
}
}



