Synchronized锁升级的原理

一、JDK 1.6版本之前

JDK1.6版本之前是没有锁升级模式的。

Synchronized在JDK1.6版本之前是通过重量级锁的方式来实现线程之间的一个锁的竞争的。之所以称它为重量级锁是因为它的底层依赖操作系统层面的Mutex Lock来去实现互斥锁的一个功能。

Mutex是系统方法,由于权限隔离的关系,应用程序调用系统方法的时候,需要切换到内核状态来执行。那这样就涉及到用户态向内核态的一个切换。这个切换会带来性能上的一个损耗。

在这里插入图片描述

二、JDK 1.6版本之后

所以在JDK1.6版本之后,Synchronized增加了锁的升级这样一个机制,来平衡数据安全性和性能的一个关系。

简单来说,就是线程去访问synchronized同步代码块的时候,synchronized根据线程的竞争情况先去尝试在不加重量级锁的情况下,去保证线程安全性。所以引入了偏向锁轻量级锁这样一个机制。

锁的分类

1. 无锁

就是没有锁的过程。

2. 偏向锁

偏向锁就是直接把当前的锁偏向于某个线程,简单来说就是通过CAS机制来修改偏向锁的一个标记。这种锁适合在同一个线程多次去申请同一个锁资源的情况并且没有其他线程竞争的一个场景中。

主要适用情况

当有一个资源,有一些线程去申请。但是这个一些线程不是一些,它是只有一个线程去申请。并且这个线程已经申请到了这个锁,没有其他的线程跟它去争抢这个锁。

那么当它进行同步代码块的执行的时候,它就没有必要释放这个锁了。因为它释放锁的过程是需要从用户态转换到内核态。然后这个过程是需要消耗很多资源的。所以说是没有必要释放的。

为了提高性能,引入了偏向锁。于是当有一个线程去执行去占有争夺这个资源的时候,它就不是释放锁了,继续持有这个锁。

3. 轻量级锁

轻量级锁也可以称为自旋锁,它是基于自适应自旋的机制,通过多次自旋去重试竞争锁。自旋锁的优点在于它可以避免用户态到内核态切换带来的一个性能损耗

Synchronized引入了锁升级这个机制之后,如果有线程去竞争锁,那么synchronized会尝试使用偏向锁的方式去竞争锁资源。如果能竞争到偏向锁,那么表示加锁成功,直接返回即可。如果竞争偏向锁失败,说明当前已经有其他线程占用的偏向锁,那么就需要将锁升级到轻量级锁,在轻量级锁的状态下,竞争锁的线程会根据自适应自旋次数去尝试自旋占用锁资源。如果在轻量级锁状态下还是没有竞争到锁的话,那么只能升级到重量级锁

升级条件

如果有两个线程去争夺这个资源的话,那么偏向锁就会升级到轻量级锁。

CAS机制

它先去判断一下这个锁是否还能够抢占到,如果抢占不到的话,它就会进行一段忙等待时间,也是自旋操作

自旋一段时间,还是没有办法获得这个锁的时候,就会升级到重量级锁了。

它是有三个值的,是包括内存地址旧的预期值要修改的新值。它是先判断一下当前的这个数据是否和自己的预期是一样的。如果是一样的,说明没有被改变过。然后它就把新的值写入进去。

原子类的底层也是用CAS来实现的。就是说原子类它只有增长和减少,它都是写好的。它都是已经封装好的,并不会让你自己去实现的。

存在问题

会有ABA问题,先把这个数据变成A然后变成B再变成A。它这个中间是有个变成B的过程的,但是如果是用这个CAS判断的话,它判断是有两个A,它是无法发现这个问题的。

但是一般来讲的话,CAS都会用版本号或者是时间戳来实现。就可能避免这个问题了。

4. 重量级锁

那么在重量级锁的状态下,没有竞争到锁的线程会被阻塞。那么这个时候线程的状态叫Blocked,也就是处于锁等待的一个状态。对于锁等待状态下的线程需要等待获得锁的线程释放锁之后触发唤醒。

实现方法

管程实现或者底层操作之类的,就完全阻塞了。

管程:一种用于并发编程的高级同步机制,旨在简化并发程序的涉及和实现。管程通过提供一个共享资源的抽象表示,并提供一些用于互斥访问和条件同步的原语,帮助程序员编写更容易理解和维护的并发代码。

设计思想

总的来说,Synchronized锁的审核及的设计思想本质上是一种性能和安全性的一个平衡。也就是说如何在不加锁的情况下,去保证线程的一个安全性,这种思想在编程领域是比较常见的。比如说MySQL里面的MVCC使用了版本链的方式来解决多个并行事务的竞争问题。

参考资料【Java面试】用架构师思维带你理解,关于Synchronized锁升级的原理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值