偏向锁

简介: 偏向锁是JVM为提升单线程环境下锁性能而引入的优化机制。其核心思想是将锁偏向首个获取它的线程,避免无竞争时的同步开销,从而提高执行效率。适用于锁由同一线程多次获取、无并发竞争的场景。一旦出现多线程竞争,偏向锁会撤销并升级为更高级别的锁。合理使用可显著提升性能,但在高并发环境下需谨慎配置。

偏向锁(Biased Locking)是Java虚拟机(JVM)为提高单线程环境下的锁性能而引入的一种优化机制。它通过偏向某个线程,避免了无竞争情况下的锁获取和释放开销,进一步提升了同步代码的执行效率。

核心原理

  1. 锁对象的偏向状态
    当锁对象第一次被线程获取时,JVM会在对象头的Mark Word中记录该线程的ID,称为偏向线程。此后,该线程再次进入同步块时,无需任何同步操作(如CAS或互斥量),直接获得锁。

  2. Mark Word的结构变化

    • 无锁状态:Mark Word存储哈希码、分代年龄等信息。
    • 偏向锁状态:Mark Word存储偏向线程ID、时间戳等信息。

偏向锁的获取与撤销流程

  1. 获取锁

    • 首次获取锁时,通过CAS操作将线程ID写入对象头Mark Word。
    • 成功后,该线程成为偏向线程,后续访问无需任何同步操作。
  2. 撤销锁
    当有其他线程尝试竞争偏向锁时,偏向锁会被撤销,恢复到无锁状态或升级为轻量级锁。撤销操作需要暂停拥有偏向锁的线程,修改Mark Word,并恢复线程执行。

偏向锁的优缺点

  • 优点

    • 无竞争时零开销:单线程重复获取锁的场景下,完全消除了CAS和互斥量的开销。
    • 实现简单:仅需修改对象头Mark Word,无需额外的数据结构。
  • 缺点

    • 偏向撤销成本高:涉及线程暂停和恢复,在竞争频繁的场景下可能成为性能瓶颈。
    • 不适用于多线程竞争:一旦发生竞争,偏向锁的撤销和升级操作会带来额外开销。

偏向锁的适用场景

  • 单线程主导的同步块:如Servlet容器处理HTTP请求的线程池。
  • 锁竞争极少发生:如初始化阶段的同步操作。
  • 锁被同一线程长期持有:如单例模式的双重检查锁定。

Java中的偏向锁示例

以下代码展示了偏向锁在单线程环境下的性能优势:

public class BiasedLockExample {
   
    private static final Object lock = new Object();
    private static int counter = 0;

    public static void main(String[] args) {
   
        // 预热JVM,触发偏向锁
        for (int i = 0; i < 1000; i++) {
   
            synchronized (lock) {
   
                counter++;
            }
        }

        // 单线程重复获取锁(偏向锁生效)
        long startTime = System.nanoTime();
        for (int i = 0; i < 1000000; i++) {
   
            synchronized (lock) {
   
                counter++;
            }
        }
        long endTime = System.nanoTime();

        System.out.println("单线程执行时间: " + (endTime - startTime) / 1000000 + " ms");
        System.out.println("Counter: " + counter);
    }
}

执行流程

  1. 预热阶段:JVM会默认延迟启用偏向锁(约4秒),首次同步块会触发偏向锁的初始化。
  2. 正式测试:单线程重复获取锁,由于没有竞争,偏向锁无需任何同步操作,执行速度极快。

JVM对偏向锁的优化

  1. 偏向锁延迟初始化
    JVM启动初期(默认4秒)禁用偏向锁,避免系统初始化阶段的竞争导致频繁撤销。

  2. 批量重偏向(Bulk Rebias)
    当一个对象被多个线程交替访问,但不存在竞争时,JVM会批量重置偏向锁,指向新的线程。

  3. 批量撤销(Bulk Revoke)
    当某个类的对象频繁发生偏向锁撤销时,JVM会将该类所有对象的偏向锁永久撤销,直接升级为轻量级锁。

偏向锁的配置参数

通过JVM参数可以调整偏向锁的行为:

  • -XX:+UseBiasedLocking:启用偏向锁(默认开启,JDK 15+默认关闭)。
  • -XX:BiasedLockingStartupDelay=0:取消偏向锁启动延迟。
  • -XX:-UseBiasedLocking:禁用偏向锁,所有锁直接升级为轻量级锁。

偏向锁与其他锁的对比

锁类型 适用场景 锁获取开销 锁释放开销 竞争处理方式
偏向锁 单线程重复获取锁 首次CAS,后续0 0 撤销并升级
轻量级锁 多线程交替获取锁 CAS CAS 升级为重量级锁
重量级锁 多线程同时竞争锁 内核互斥量 内核互斥量 线程阻塞

总结

偏向锁是JVM针对单线程场景的极致优化,通过消除无竞争情况下的同步开销,显著提升了性能。但在多线程竞争频繁的场景下,偏向锁的撤销和升级操作可能成为性能瓶颈,此时应考虑禁用偏向锁或使用其他并发工具。理解偏向锁的工作原理有助于优化高并发系统的性能。

目录
相关文章
|
前端开发 Java 开发者
Spring Boot 3 集成 Thymeleaf
Thymeleaf是一款用于Web和独立环境的现代化服务器端Java模板引擎。它能够处理HTML、XML、JavaScript、CSS甚至纯文本。Thymeleaf的语法简单易懂,它允许开发者在模板中嵌入表达式,以便动态地渲染数据。
573 1
Spring Boot 3 集成 Thymeleaf
|
弹性计算 安全 Linux
Linux服务器总是被暴力破解,用fail2ban来加强防护(用法详解)
Linux服务器总是被暴力破解,用fail2ban来加强防护(用法详解)
Linux服务器总是被暴力破解,用fail2ban来加强防护(用法详解)
|
Oracle Java 关系型数据库
Oracle jdk 的国内下载镜像
Oracle jdk 的国内下载镜像
61550 0
|
11月前
|
存储 Java 对象存储
轻量级锁
轻量级锁是JVM为提升多线程性能而引入的锁机制,通过CAS操作减少线程阻塞,适用于同步块执行时间短且线程竞争不激烈的场景。其核心在于使用栈帧中的锁记录与CAS操作实现高效加锁,避免用户态与内核态切换带来的性能损耗。当无竞争时,仅需一次CAS即可完成锁获取;若竞争激烈,则可能升级为重量级锁。相比偏向锁和重量级锁,轻量级锁在低竞争环境下具有更高的效率。
315 0
|
11月前
|
缓存 Java
对比 synchronized 和 volatile
`synchronized` 和 `volatile` 是 Java 并发编程中的两个关键机制,各有侧重。`synchronized` 用于实现线程的互斥访问,保证原子性、可见性和有序性,适用于需要锁的场景;而 `volatile` 更轻量,仅确保变量的可见性和有序性,适用于状态标志等无需复合操作的场景。两者可互补使用,如双重检查单例中结合二者优势。合理选择有助于提升并发性能与代码安全性。
487 0
|
11月前
|
监控 Java 关系型数据库
排他锁
排他锁(写锁)是一种互斥机制,确保同一时间仅一个线程访问共享资源,保障数据一致性与完整性。适用于写操作场景,如更新、删除等,常见于数据库和多线程编程。其优点为强一致性和实现简单,但并发度低且存在死锁风险。可通过synchronized、ReentrantLock等方式实现。
317 0
|
11月前
|
缓存 Java 关系型数据库
共享锁
共享锁允许多个线程同时读取共享资源,写操作时阻塞其他线程,通过“读共享、写独占”策略提升并发性能,适用于读多写少场景,如缓存、数据库查询等。
360 0
|
11月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
1335 0
|
8月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
656 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台

热门文章

最新文章