java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java锁升级机制

Java锁升级机制超详细讲解(附实例代码)

作者:java金融

Java中的synchronized锁会经历一个从无锁到偏向锁,再到轻量级锁,最后到重量级锁的升级过程,这种优化称为锁升级或锁膨胀,这篇文章主要介绍了Java锁升级机制超详细讲解的相关资料,需要的朋友可以参考下

引言

最近有个三年左右的兄弟面试java 被问到这样一道经典的八股文面试题: 你讲讲java里面的锁升级? 他感觉回答的不是很好,然后回去找资料学习了一波,然后下面是他输出的文章,希望对找工作的其他朋友也有些帮助。

1. 概述

Java 的锁升级机制是 JVM 在 JDK 1.6 后引入的重要优化策略,目的是在多线程环境下平衡 线程安全 与 性能开销。通过动态调整锁的复杂度,JVM 根据竞争强度逐步升级锁的状态,避免在低竞争场景下使用高成本的重量级锁。

2. 锁类型及特点

锁类型适用场景性能开销核心机制
无锁(Unlocked)无线程竞争极低直接通过 CAS 操作尝试获取锁。
偏向锁(Biased Locking)单线程重复访问(无竞争)极低对象头记录偏向线程 ID,后续同一线程无需竞争,直接获取锁。
轻量级锁(Lightweight Lock)低竞争(多个线程交替访问)中等通过 CAS 自旋尝试获取锁,避免操作系统级别的阻塞。
重量级锁(Heavyweight Lock)高竞争(长时间阻塞或高并发)依赖操作系统互斥量(Mutex),线程被挂起并排队等待。

3. 锁升级的过程

锁升级路径为:无锁 → 偏向锁 → 轻量级锁 → 重量级锁,且 不可逆(只能升级,不能降级)。

3.1 无锁 → 偏向锁

3.2 偏向锁 → 轻量级锁

3.3 轻量级锁 → 重量级锁

4. 锁升级的优缺点

4.1 优点

4.2 缺点

5. 锁升级的优化策略

5.1 减少锁持有时间

5.2 使用分段锁(Segment Locking)

5.3 禁用偏向锁

5.4 调整自旋次数

6. 代码示例

public class LockUpgradeExample {
    private final Object lock = new Object();

    public void performTask() {
        synchronized (lock) {
            // 同步代码块
        }
    }

    public static void main(String[] args) {
        LockUpgradeExample example = new LockUpgradeExample();
        Thread t1 = new Thread(example::performTask);
        Thread t2 = new Thread(example::performTask);

        t1.start(); // 初始为偏向锁(t1)
        t2.start(); // 触发偏向锁撤销,升级为轻量级锁
    }
}

7. 关键 JVM 参数

参数作用
-XX:+UseBiasedLocking开启/关闭偏向锁(默认开启,Java 15+ 默认关闭)。
-XX:BiasedLockingStartupDelay=0立即启用偏向锁(避免延迟)。
-XX:PreBlockSpin设置轻量级锁自旋次数(默认 10)。
-XX:-UseSpinning关闭自旋锁(强制进入重量级锁)。

8. 总结

通过合理设计代码(如减少锁粒度、避免过早膨胀到重量级锁),可以最大化 Java 的并发性能。

到此这篇关于Java锁升级机制的文章就介绍到这了,更多相关Java锁升级机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文