锁的升级过程

前置概念

首先我们要了解到锁的四种状态:无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态。

无锁状态

在无锁状态下,没有线程持有锁。这意味着任何线程都可以自由地访问和修改共享资源,而不需要进行同步或互斥。无锁状态是最理想的情况,因为它不会引入任何额外的开销或阻塞。

偏向锁状态

当只有一个线程访问锁时,可以将锁设为偏向锁。偏向锁的目标是减少线程竞争,提高单线程场景下的性能。在偏向锁状态下,锁会记录当前持有锁的线程的标识。当其他线程访问锁时,它们会检查偏向锁的标识,如果与自己的线程标识匹配,则无需竞争锁,直接进入临界区。这样做可以减少锁的粒度,提高性能。

轻量级锁状态

轻量级锁使用 CAS(Compare and Swap)操作来实现锁的加锁和解锁,避免了传统的互斥量和阻塞机制。在轻量级锁状态下,线程会通过 CAS 操作尝试将锁的状态从偏向锁升级为轻量级锁。

重量级锁状态

重量级锁使用操作系统提供的底层互斥量机制实现,通过阻塞和唤醒线程来实现互斥。在重量级锁状态下,线程会进入阻塞状态,等待锁的释放。当锁被释放时,等待的线程会被唤醒并进行竞争,获取锁后进入临界区。

锁的升级过程

首先当没有现成持有锁时,该对象处于无锁状态。任何线程都可以自由的访问和修改该对象。

无锁->偏向锁

当有一个线程第一次访问处于无锁状态的对象时,JVM会将该对象的锁设置为偏向锁,并将该线程的ID记录在锁的对象头中。这样,当该线程再次访问该对象时,无需进行锁竞争和互斥操作,直接获取偏向锁,从而提高性能。当其他线程尝试访问该对象时,它们会检查偏向锁的标识,如果与自己的线程标识匹配,则无需竞争锁,直接进入临界区。

偏向锁->轻量级锁

当有多个线程尝试获取同一个对象的锁时,偏向锁会失效。当偏向锁失效后,JVM会尝试将锁升级为轻量级锁。此时,它会使用 CAS(Compare and Swap)操作来尝试获取锁。如果其他线程已经获取到了轻量级锁。此时,该现成会进入自旋获取锁的状态等待获取。

轻量级锁->重量级锁

当一个线程尝试获取轻量级锁失败时,JVM会将轻量级锁的状态标记为“膨胀”(Inflated)。
轻量级锁膨胀为重量级锁时,JVM会将对象的锁状态从轻量级锁转换为重量级锁。这个过程涉及到锁对象的内部数据结构的改变,使得锁的状态由线程自己管理转换为由操作系统底层的互斥量来管理。
当一个线程尝试获取重量级锁时,它会使用底层的互斥量(如操作系统提供的锁机制)来实现互斥。如果其他线程已经持有了重量级锁,那么等待的线程将进入阻塞状态,直到持有锁的线程释放锁。一旦锁被释放,等待的线程将被唤醒并进行竞争,获取锁后进入临界区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值