Java面试题(九):synchronized

1. 对象信息的存储

对象的信息实际上是存在与堆中的,而方法区中则是存类的信息。
在这里插入图片描述
为什么非要8的整数倍?
答:可以保证内存的利用率

1.1. 对象头

  1. MarkWord
  2. 类指针
  3. 数组长度

1.2. 属性信息

存储属性相关信息

1.3. 对齐字节

保证一个对象的大小必须是8的整数倍
为什么非要8的整数倍?
答:可以保证内存的利用率

在JVM垃圾回收的时候,会产生很多内存碎片,比如一个对象大小是7,被回收后留下一个长度位7的空间,再来一个对象大小为8,就利用不了这个空间,所以要尽可能保证对象的内存大小一致,提高内存的复用。

2. 对象头中的MarkWord

MarkWord是sync实现的关键点
在这里插入图片描述
对于每一个刚new出来的对象,它的结构是这样的
在这里插入图片描述
我们注意几个关键字,age,biased_lock,lock。
age是表示这个对象的年龄,也就是JVM垃圾回收里面的新生代老年代,age占四位,所以分代年龄的最大值是15。
biased_lock和lock是和对象锁有关的东西

  • 对象的锁状态对应编码表示
    在这里插入图片描述
    在这里插入图片描述
    对象产生后,过一段时间,会自动从正常状态变成偏向锁
    偏向锁:只能一个线程使用,该线程不用获取锁,拿到锁的效率高。
    当偏向锁发生率别的线程对它的争抢,那么java虚拟机会将这个偏向锁升级为轻量级锁

3. synchronized锁升级机制

在每一个对象被创建的时候,都会同步产生另一个对象,叫做Monitor(对象监视器),当一个线程获取这个对象锁的时候,实际上是获取了这个对象的对象监视器,一个对象只有一个对象监视器,被一个线程获取到后,其余线程就获取不到了。这种状态效率很低
所以在JDK1.6后,对sync做了优化(锁升级),当sync升级为重量级锁,才是获取monitor的状态
当一个对象一直只有一个线程访问的时候,在JDK1.6前,每一次的访问,也会获取monitor和释放monitor,这让程序效率很低,所以在JDK1.6后,实现了偏向锁,当一个对象只有一个线程访问的时候,那这个线程在访问这个对象的时候不需要获取锁。

3.1. 无锁状态 -> 偏向锁状态

在这里插入图片描述
当一个对象的锁,在一段时间内,总是只有一个线程会获取,那么这个对象的锁就会升级为偏向锁,偏向锁是只有这一个线程可以使用,省掉了moniter的一个切换,效率提高。

3.2. 偏向锁 -> 轻量级锁

当有另一个线程同样来获取一个对象的偏向锁的时候,发现那个锁已经被获取率,而且只能是markword线程ID的那个线程才能获取,所以就会暂停持有偏向锁的那个线程,并且撤销掉该对象的偏向锁。
在这里插入图片描述
我们从上面的图可以发现,当偏向锁转换为轻量级锁的时候,markword的值发生了极大的变化,而且锁迟早也会被释放掉,变成正常状态,所以我们需要把正常状态下的markword存储起来,再更改markword的值
轻量级锁的前62位,存储的就是lock record的地址
在这里插入图片描述
在这里插入图片描述
一旦升级后,这个锁永远只能是轻量级锁(只能向上升级,不能向下降级)
其实在JDK1.6后,实现的这个锁升级机制,原理就是CAS对markword的比较替换来实现的,比JDK1.6前,直接获取moniter的效率要好多了。

3.3. 轻量级锁 -> 重量级锁

当一开始就发生锁的争抢的时候,这个对象的状态会被直接升级为轻量级锁
在这里插入图片描述
线程2尝试获取轻量级锁,发现markword已经不是正常状态下了,已经被其它线程修改成轻量级锁了,所以就会一直CAS自旋等待markword变回正常状态,自己再去替换(在一定时间内,线程2替换成功,锁不会升级)
在这里插入图片描述
自旋就是一个死循环的状态,这样的状态特别消耗cpu,所以自旋状态的保持会有一个时间段,过了这个时间段后,自旋状态的这个线程会把markword升级为重量级锁
在这里插入图片描述
重量级锁就是JDK1.6前的,获取对象的moniter。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

若能绽放光丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值