synchronized 是 Java 中实现线程同步的核心机制,其锁状态会随着竞争激烈程度动态升级,以提高并发性能。从 无锁 到 重量级锁 的升级过程包括四个阶段,且 不可逆。以下是具体流程及原理:
01
01
(偏向锁标识位为 1
)。00
。10
。锁状态 | 触发条件 | Mark Word 变化 |
---|---|---|
无锁 | 对象初始化时 | 哈希码 + 分代年龄 + 锁标志位 01 |
偏向锁 | 首次线程访问同步块 | 线程 ID + 锁标志位 01(偏向标识位 1) |
轻量级锁 | 多线程交替竞争或偏向锁撤销 | 栈帧锁记录指针 + 锁标志位 00 |
重量级锁 | 自旋失败或竞争线程数过多 | Monitor 指针 + 锁标志位 10 |
优点 | 缺点 |
---|---|
减少无竞争场景下的同步开销 5 54 | 重量级锁的阻塞机制导致高延迟 11 72 |
自适应不同并发场景,平衡性能与安全性 11 | 锁升级不可逆,可能过度升级到重量级锁 54 |
ReentrantLock
或 StampedLock
提升灵活性通过理解锁升级机制,开发者可以更好地优化多线程程序的性能,避免因锁竞争导致的性能瓶颈
import org.openjdk.jol.info.ClassLayout;
public class LockUpgradeExample {
public static void main(String[] args) throws InterruptedException {
// 创建一个对象
Object obj = new Object();
System.out.println("===== 初始状态(无锁) =====");
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
// 偏向锁延迟(默认 4s),确保偏向锁生效
Thread.sleep(5000);
// 首次获取锁,触发偏向锁
synchronized (obj) {
System.out.println("===== 偏向锁状态 =====");
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
// 创建多个线程竞争锁,触发轻量级锁
for (int i = 0; i < 2; i++) {
new Thread(() -> {
synchronized (obj) {
System.out.println("===== 轻量级锁状态 =====");
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
}).start();
Thread.sleep(1000);
}
// 高竞争场景,触发重量级锁
for (int i = 0; i < 3; i++) {
new Thread(() -> {
synchronized (obj) {
System.out.println("===== 重量级锁状态 =====");
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
}
}).start();
}
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。