锁的优化
约 539 字大约 2 分钟
2025-09-20
[[线程安全#synchronized|synchronized]]的锁实现
public class SynchronizedDemo2 {
Object object = new Object();
public void method1() {
synchronized (object) {
}
method2();
}
private static void method2() {
}
}字节码文件为
通过monitorenter和monitorexit执行能够对象的锁计数器加一或减一,每一个对象在同一时间只能与一个monitor相关联,而一个monitor在同一时间只能被一个线程获得 
JVM 的monitorenter与monitorexit字节码依赖于底层操作系统的Mutex Lock实现,但Mutex Lock需要将当前线程挂起并进入内核态执行,切换的代价很昂贵,而大多数情况下可能只有单线程在进行,并不存在锁竞争,因此可以对锁的实现进行优化
锁的类型
JDK1.6+ 的 Synchronized 同步锁有四种状态
- 无锁
- 偏向锁
- 轻量级锁
- 重量级锁 随着锁竞争越来越激烈,由上到下逐渐升级,锁可以升级但不可以降级 32bit 下对象头的 mark word

偏向锁
对于只有单线程不存在锁竞争的环境下,一个锁总是由一个线程获取,频繁的获取锁与释放锁会带来不必要的性能开销 若线程检查到对象是偏向锁,就会检查是否由当前线程持有,若是将直接执行同步代码,若不是则会尝试 CAS 获取竞争锁,若竞争失败将在下一个全局安全点升级为轻量级锁
轻量级锁
轻量级锁即自旋锁,没有抢到锁的线程将自旋,不断尝试获取锁,这对于能够很短时间内释放的锁能够避免用户态到内核态的开销 对于多次内旋无法获取到锁,为了避免自旋照成的 CPU 开销,会将锁升级为重量级锁
重量级锁
若线程无法获取到锁,且锁为重量级锁,线程将会进入等待队列,等待被唤醒
