一文详细:synchronized关键字的底层原理 及 锁升级

(一)synchronized关键字的底层原理

一、基本使用

在这里插入图片描述

二、Moniter

synchronized底层实际上就是Moniter。
在这里插入图片描述
为什么会释放两次对象锁,因为在底层使用了一个隐式的try…finally…,以防正常的代码在执行过程中抛异常,也就不走第一个解锁。
还需要研究一下 monitor的工作机制
在这里插入图片描述

(1)Owner与EntryList

lock做为一个对象锁,首先会与monitor进行关联,并判断monitor的owner属性是否为null,若为null则会直接赋予lock对象锁给该线程,并且使owner属性关联本线程。此时线程二进来,发现owner已经绑定了线程一,线程二就不能再拥有该锁,要到EntryList中进行等待。即便有其他线程进来也是如此,且他们都会处于BLOCKED 阻塞状态。直到线程一执行完毕并释放锁,owner属性就会变回null并唤醒EntryList当中的线程,且让这些线程去争夺owner的拥有权(EntryList当中的线程没有先来后到的关系)。

(2)WaitSet

当某线程调用wait方法后,就会处于等待状态并放入WaitSet当中。

三、总结

在这里插入图片描述

(二)锁升级

在这里插入图片描述

用户态指的是自己编写的java代码,内核态指的是CPU层面的东西。这两者的资源权限不同,而用户态的权限较低,内核态的权限较高。因为JVM是系统级别的,属于内核态,而Monitor又是属于JVM来管理的,这中间涉及的切换的成本较高,而且进程的上下文切换的性能也较低。所以Monitor实现的锁的性能整体不高,也就称为重量级锁。

前面提到某线程在获取锁时,需要让对象锁与Monitor进行关联,但他们是如何关联上的呢?主要还是跟lock对象锁有关系。
在这里插入图片描述

一、Java对象的内存结构

在JVM内存结构中,我们创建的对象都存储在堆当中,HotSpot也就是JVM虚拟机的一种实现。

就是MarkWord描述了对象与monitor的关联关系,接下来将重点去讲解。
因为HotSpot虚拟机的内存管理系统,要求内存的起始地址必须为8的倍数,所以需要用到对齐填充。
在这里插入图片描述

二、MarkWord

在这里插入图片描述
ptr_to_heavyweight_monitor指的是指针,指向重量级锁所需要关联的monitor,实际上就是通过在此处记录monitor的地址,等于将对象与monitor进行关联。
在这里插入图片描述

三、轻量级锁

(1)加锁流程

在这里插入图片描述

当某线程进入同一把锁两次,就叫做锁重入。因为都是同一个线程持有的锁,所以就不存在竞争,也没必要使用monitor来实现,这时可以优先使用轻量级锁。

轻量级锁的工作原理
当某线程将要去执行method1方法,此时就会创建一个锁记录Lock Record。每个线程的战争都包含了一个锁记录的结构,内部存储锁定对象的MarkWord。首先会让Object reference指定锁对象,而当当前线程持有锁时,会借助Lock Record(锁记录地址)去修改当前锁对象的MarkWord,这里主要使用CAS的方式去交换数据。

  • CAS可以理解为保证在修改数据时是一个原子操作
  1. CAS交换成功
    当CAS交换成功,就会在对象头存储锁记录的状态和状态,表示由该线程持有当前的对象锁。
    CAS交换前:
    在这里插入图片描述
    CAS交换后:
    在这里插入图片描述
  2. CAS交换失败
    当CAS交换失败,可能是因为出现多个线程竞争,这时轻量级锁会直接升级为重量级锁;也可能是因为当前出现锁重入,这时就会在战争中再去添加一条Lock Record,做为重入计数,并且进行多次CAS交换数据,通过Lock Record的个数来表示当前线程重入了几次。
    在这里插入图片描述

(2)解锁流程(synchronized代码块执行完毕)

  1. 首先判断当前的锁记录是否为null,若为null则表明存在锁重入,就需要删去当前的锁记录,代表一处synchronized代码块执行完毕。
    在这里插入图片描述
  2. 若当前锁记录不为null,就会再次执行CAS操作,把对象头原先的值交换回来,这样就算解锁成功。
    在这里插入图片描述

(3)总结

在这里插入图片描述

四、偏向锁

在这里插入图片描述
偏向锁的执行流程:

  1. 首次加锁
    这次锁记录地址与对象的MarkWord需要进行CAS交换的数据内容不一样,会直接将当前线程的id写入,并将偏向锁标志改为1
    在这里插入图片描述
  2. 重复加锁(锁重入)
    首先也会去添加锁记录,但是这次不会再去执行CAS操作,只会去判断当前对象的MarkWord中的线程id是否为自己的,是的话只需记录当前的重入次数即可。
    在这里插入图片描述

四、总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Craaaayon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值