Synchronization 原理分析

目录

 

一、Synchronization原理分析

二、Synchronization数据存放格式

2.1、数据存放    

2.2、偏向锁

2.3、轻量级锁

2.3、重量级锁

2.4、性能场景比较


一、Synchronization原理分析

        Synchronization 锁原理是对象同步通过Monitor 来实现的,java每个对象都会有Monitor锁标记,代码块同步使用的是MONITORENTER和MONITOREXIT来同步;类似于操作系统的PV操作,MONITORENTER会执行+1操作,而MONITOREXIT会执行-1操作。

二、Synchronization数据存放格式

2.1、数据存放    

Synchronization存放在对象的头部,总共有两种类型,分别是对象和数组类型,不同的类型存放的格式有所差异,普通对象类型暂用3字宽,数组类型占用2字宽,1字宽=4字节=32bit(32位虚拟机),锁只能升级不能降级,如下图,偏向锁升级为轻量级锁之后不能在降级为偏向锁了。

java对象头(32位虚拟机)
锁状态25bit4bit1bit2bit
23bit2bit是否是偏向锁锁标志位
无锁状态对象hashCode对象分代年龄001
轻量级锁指向栈中锁记录的指针00
重量级锁指向互斥量的指针10
GC标记   
偏向锁线程IDEpoch对象分代年龄101

 

 

 

 

 

 

 

 

2.2、偏向锁

从数据结构中可以看出,记录当前线程访问的ID,如果同一个线程访问同一个同步块时,减少加锁和解锁操作,直接使用同步快就可以了,降低了获取锁和加锁的开销。

偏向锁不会主动撤销锁,只有当其他线程竞争资源的时候才会释放锁,变成无锁状态,变成为无锁状态需要当先线程已经执行完了同步块,否则竞争线程会需要等待资源释放。一旦锁资源释放,会唤醒竞争等待的线程。

偏向锁调整相关参数设置,关闭延迟:-XX:BiasedLockingStartUpDelay=0;关闭偏向锁:-XX:UseBiasedLocking=true

2.3、轻量级锁

加锁:(1)在当前线程栈帧空间创建存储对象头MarkWord空间;(2)复制对象MarkWord至(1)创建的空间;(3)使用CAS操作将对象头中的MarkWord替换为指向当前线程所记录的指针,成功表示获取锁,失败表示未获取到锁。

解锁:使用CAS将当前线程的栈帧中保存的MarkWord替换,回到原来的对象头,如果成功,表示当前没有竞争资源失败会自旋重新获取,超过一定阈值之后,会升级为重量级锁,轻量级锁升级为重量级锁之后,没法在降级为轻量级锁了

2.3、重量级锁

有轻量级锁升级为重量锁,其锁保存了互斥量的指针,并且会阻塞当前线程,当一旦有锁释放之后,会唤醒当前阻塞的线程。

2.4、性能场景比较

锁名称优点缺点
偏向锁单个线程获取锁无需加锁和解锁步骤,降低加锁和解锁开销、使用一个线程多次访问同步多个线程或存在锁竞争,多一个锁撤销开销
轻量级锁竞争线程不会阻塞,响应速度快自旋会消耗CPU资源
重量级锁吞吐量高线程阻塞,响应时间慢

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值