64位指针膨胀 java_【小知识探究系列四】synchronized的加锁原理和膨胀过程探究(以64位jvm为例)...

一、synchronized加锁原理

由于synchronized总体的工作原理是通过操作对象头来实现加锁和解锁,因此在具体的了解synchronized之前,首先需要简单了解一下对象头。

所谓对象头其实是每个对象都存在的一份存储当前对象gc分代年龄、hashcode、锁标记、当前获取到锁的线程ID等信息的一块内存区域。对象头主要分为以下三块:

1.Mark Word

2.指向类的指针

3.数组长度(只有数组对象才有)

synchronized在加锁过程中主要对mark word进行操作,因此主要对mark word的划分,各个划分快存储的内容进行探索。如下图所示mark word的划分以及各个划分块存储的内容:

44ea2c3b825f7a173b699e2f20ecb6c3.png

在64位jvm中mark word的长度为64bit,从图中我们可以看出最后两位用来作为锁标记位,在无锁和偏向锁状态时还存在1bit的偏向锁位用来标记是否是可偏向的。

我们可以使用jol来查看对象头信息,要是有jol需要引入如下包:

org.openjdk.jol

jol-core

0.8

执行以下代码我们可以简单看一下对象头信息:

Object o=new Object();

System.out.println(VM.current().details());

System.out.println(ClassLayout.parseInstance(o).toPrintable());

执行结果:

d74732fb1dfcfded175bc4b7898a5112.png

从执行结果我们可以看到对象头总共占了96bit【空框1】,其中mark Word占了64bit【红框2】,最后三位的状态为001说明当前处于无锁状态。

从上边我们知道了synchronized在加锁解锁时操作的内存空间,那么synchronized是如何操作的,在什么时候进行操作,操作了什么内容呢,下文将进一步了解。

使用javap反编译工具对含有synchronized代码块的代码进行反汇编,执行javap -v App.class的运行结果:

10300627592cc60b63fb435a02b79952.png

可以看到在被synchronized包起来的代码块前后增加了monitorenter和monitorexit两条汇编指令,当代码执行到monitorenter指令时开始加锁操作,大概执行过程如下:

在代码进入代码块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的栈帧中建立一个名为Lock Record的空间,用于存储锁对象目前的Mark Word的拷贝,然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为Lock Record的指针。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且队形Mark Word的锁标志位(Mark Word的最后两个bits)将转变为‘00’,即表示此对象处于轻量级锁定的状态。

—深入理解JVM

二、synchronized锁膨胀过程

锁膨胀是从偏向锁—>轻量级锁---->重量级锁的转换过程。在探究膨胀过程之前,我们先简单了解一下偏向锁、轻量级锁、重量级锁的概念。

①重量级锁:传统重量级锁指使用操作系统互斥量来实现加锁(PV操作),使用这种锁的话,即使没有所竞争的时候还是会调用操作系统级别的互斥量实现加锁,造成性能消耗。

②轻量级锁:通过简单的数据操作实现加锁,不需要调用OS级别的加锁机制。

*在当前线程自己的栈区创建Lock Record用于存储Object的Mark Word的拷贝

*将Mark Word副本存入lock record

*基于CAS的机制将Object的Mark Word跟新为执行Lock record的指针

*如果CAS跟新成功,则当前线程获取到锁,否则检查Mark Word出的指针是否指向自己的栈针

*如果指向自己的栈针,则说明已经获取到锁,则重入代码快执行,否则说明锁已经被占用,则膨胀为重量级锁

③偏向锁:偏向锁可以说是在轻量级锁上的进一步优化,轻量级锁在没有锁竞争的条件下还需要执行CAS操作,偏向锁连CAS都不操作。所谓“偏”就是说偏袒于第一次获得锁的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将不需要执行同步操作,直接获得运行资源。直到另外一个线程到来,偏向锁开始膨胀。

1.配置虚拟机开启偏向锁

-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值