Synchronized锁升级

目录

        一、升级的原因

        二、偏向锁

        三、轻量级锁

        1.定义

        2.轻量级锁的加锁和解锁

       四、重量级锁


        一、升级的原因

        我们可能在学习的过程中有听到过synchronized锁升级这句话,那么为什么要进行锁升级呢?

        原因是因为,在Java1.5以前,synchronized还没有进行优化,一旦使用synchronized进行加锁之后,直接就是从无锁到重量级锁,而重量级锁的底层是依靠OS的Mutex Lock去实现互斥锁的功能的,Mutex是系统方法,在调用时需要从用户态转向内核态才能执行,消耗资源较大;并且,并不是加锁之后就一定是多线程并发访问被锁内容,因此就会造成资源的浪费。

        所以,在Java1.6之后,JDK对synchronized实现了一些优化,引入了偏向锁和轻量级锁。

        二、偏向锁

        偏向锁(Biased Locking):是针对无竞争情况下的同步操作进行的优化手段。偏向锁在对象的对象头中的Mark Word字段中记录获取锁的线程ID。当一个线程获取了锁之后,如果再次进入同步块,就无需再进行加锁的操作,可以直接获取锁,避免了重复加锁解锁的开销。偏向锁的目标是优化无竞争场景下的性能表现。

        三、轻量级锁

        1.定义

        轻量级锁(Lightweight Locking):轻量级锁是为了解决短时间内的竞争而引入的优化机制。当一个线程请求获取锁时,JVM会将对象头中的Mark Word字段复制到自己的线程栈帧中,并通过CAS(比较并交换)操作尝试将对象的状态从无锁状态转换为轻量级锁状态。如果竞争成功,则进入临界区执行,如果竞争失败,则升级为重量级锁。轻量级锁的目标是提供更快的锁获取和释放操作。

        2.轻量级锁的加锁和解锁

加锁过程:

  1. 当一个线程尝试获取锁时,首先会在对象的Mark Word字段中记录锁的指针。如果该对象的锁状态是无锁状态(Unlocked)或者是偏向锁状态(Biased),那么线程可以直接使用CAS(比较并交换)操作将锁状态改为轻量级锁状态(Lightweight Locked)。这个转换过程是无锁的,不涉及线程之间的竞争。
  2. 如果CAS操作成功,表示该线程成功获取到了轻量级锁,它继续执行临界区的代码。

解锁过程:

  1. 当一个线程执行完临界区的代码后,准备释放轻量级锁时,它先使用CAS操作将对象的Mark Word字段恢复为无锁状态(Unlocked)。如果CAS操作成功,表示该线程成功释放了轻量级锁,其他线程可以竞争获取锁。
  2. 如果CAS操作失败,表示有其他线程正在竞争该锁,那么当前线程会膨胀为重量级锁(Heavyweight Lock)。这时,会在操作系统层面调用阻塞机制,将当前线程挂起,等待唤醒并重新竞争锁。

        总的来说,轻量级锁的加锁和解锁过程是通过CAS操作来改变对象的锁状态,避免了阻塞等待的开销。如果CAS操作成功,线程成功获取/释放锁并继续执行;如果CAS操作失败,说明有竞争存在,线程会膨胀为重量级锁,进入阻塞状态等待唤醒。

       四、重量级锁

        重量级锁(Heavyweight Locking):重量级锁是Java中最基本、最传统的一种锁形式。当多个线程竞争同一个锁时,只有一个线程能够获取到锁,其他线程则被阻塞等待。当持有锁的线程执行完临界区的代码后,释放锁,被阻塞的线程中的一个会被唤醒并获取锁,继续执行。重量级锁的目标是保证多线程环境下的数据安全性。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值