java锁的升级过程

无锁,偏向锁,轻量级锁,重量级锁
jdk1.6后减少锁的消耗时,引入偏向锁和轻量级锁,锁可以升级但不能降级。

因为自旋会消耗CPU,为了避免无用的自旋(比如获得锁的线程被阻塞住了)一旦锁升级成重量级锁,就不会再恢复到轻量级锁状态。当锁处于这个状态下,其他线程试图获取锁时,都会被阻塞住,当持有锁的线程释放锁之后会唤醒这些线程,被唤醒的线程就会进行新一轮的夺锁之争

锁分级别原因

没有优化以前,synchronized是重量级锁(悲观锁),使用 wait 和 notify、notifyAll 来切换线程状态非常消耗系统资源;线程的挂起和唤醒间隔很短暂,这样很浪费资源,影响性能。所以 JVM 对 synchronized 关键字进行了优化,把锁分为 无锁、偏向锁、轻量级锁、重量级锁 状态。

无锁:没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功,其他修改失败的线程会不断重试直到修改成功。

偏向锁
由同一线程多次获得,不存在竞争情况,所以当一个线程访问同步块并 获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出 同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需 要再测试一下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁):如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。

对象的代码一直被同一线程执行,不存在多个线程竞争,该线程在后续的执行中自动获取锁,降低获取锁带来的性能开销。偏向锁,指的就是偏向第一个加锁线程,该线程是不会主动释放偏向锁的,只有当其他线程尝试竞争偏向锁才会被释放。

偏向锁的撤销,需要在某个时间点上没有字节码正在执行时,先暂停拥有偏向锁的线程,然后判断锁对象是否处于被锁定状态。如果线程不处于活动状态,则将对象头设置成无锁状态,并撤销偏向锁;

如果线程处于活动状态,升级为轻量级锁的状态。

轻量级锁:轻量级锁是指当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。

当前只有一个等待线程,则该线程将通过自旋进行等待。但是当自旋超过一定的次数时,轻量级锁便会升级为重量级锁;当一个线程已持有锁,另一个线程在自旋,而此时又有第三个线程来访时,轻量级锁也会升级为重量级锁。

重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。

重量级锁通过对象内部的监视器(monitor)实现,而其中 monitor 的本质是依赖于底层操作系统的 Mutex Lock 实现,操作系统实现线程之间的切换需要从用户态切换到内核态,切换成本非常高。

### Java 升级机制原理及过程Java中,升级是为了优化同步操作的性能而设计的一种机制。当多个线程尝试访问同一个资源时,JVM会根据不同的情况调整的状态以提高效率。 #### 初始状态:无 当没有任何线程持有对象上的时,该对象处于未定状态。此时的对象头中的Mark Word仅存储对象的元数据信息[^2]。 #### 偏向 一旦有第一个线程请求获取此对象上的,则进入偏向模式。在此阶段,JVM会在对象头部记录下当前拥有的线程ID,并标记为偏向。对于后续来自同一线程对该的操作,无需再执行昂贵的竞争检测逻辑;只要确认是相同的线程再次访问即可直接允许其继续运行。这种处理方式极大地减少了单一线程场景下的同步成本。 ```java synchronized (object) { // Critical section code here... } ``` #### 轻量级 然而,如果有其他不同线程也试图获取相同对象上的,在发现已有另一个活动线程正在占用的情况下,原先持有的偏向会被撤销并转换成轻量级。这时两个或更多线程之间会发生短暂的竞争状况——通过自旋等待的方式轮流争取所有权直到其中一个成功为止。这种方式可以避免立即陷入更耗资源的操作系统级别的阻塞调度流程。 #### 重量级 假如上述自旋未能快速解决问题(即存在长时间持续不断的高并发争用),那么最终将会升级到重量级形式。这意味着所有参与竞争的线程都将被挂起放入操作系统内核态队列里排队等候CPU时间片分配来重新争夺监视器控制权。这显然不是最理想的解决方案因为涉及到上下文切换所带来的巨大开销。 #### 升级顺序总结 整个过程级别按照如下路径逐步提升: 1. **无** 2. **偏向** —— 当首次遇到新的独占线程时启用 3. **轻量级** —— 发生跨线程共享需求时转变而来 4. **重量级** —— 如果频繁发生冲突则进一步恶化至此形态 值得注意的是,这些变化都是透明地由虚拟机内部管理完成,开发者通常不需要显式干预这一过程
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值