Java锁机制和锁优化 - 1

在这里插入图片描述
在java中,每个object,也就是每个对象都拥有一把锁,这把锁存放在对象头中,锁中记录了当前对象被那个线程所占有。

对象的结构*

在这里插入图片描述

对象头的结构

这里可以参考一篇博客:点我查看
在这里插入图片描述
在Java中synchronized被Java编译之后产生的字节码指令monitorenter, monitorexit,依赖这两个指令能够使线程体同步。
在这里插入图片描述使用这两个指令对业务代码进行了包裹
在这里插入图片描述Monitor ——>管程/监视器
在这里插入图片描述你可以将monitor理解成只能容纳一个人的房间,当一个人进入房间的时候,其他人只能等待,只有当这个人出来之后,其他人才能才有进入的机会。
在这里插入图片描述
但是存在性能问题,因为synchronized被编译之后实际上是monitorenter和monitorexit两个字节码指令,而monitor依赖的是操作系统的mutex lock来实现的。
java线程实际上是对操作系统线程的映射,所以每当挂起或者唤醒一个线程,都要切换擦作系统的内核态,这种操作时比较重量级的。
所以java6引入了偏向锁和轻量级锁。
在这里插入图片描述针对于锁到底能不能降级,如下:
在这里插入图片描述

锁的4种状态

1、无锁

所有线程都能够访问到同一个资源,这就可能出现两种情况:

  1. 无竞争
  2. 存在竞争,非锁方式同步线程(CAS)
    在这里插入图片描述

2、偏向锁

偏向锁如果这个对象能够认识这个线程,当这个线程来的时候直接会交出锁,偏爱这个对象,就叫偏向锁
当为偏向锁的时候,是根据mark word的前23bit来确定当前获得所得线程,如果下次还是还是这个id,那就直接给,但是如果下次的不一样,就代表有多个线程在争抢锁,那就升级为轻量级锁。

3、轻量级锁

将前30bit转换为指向栈中所记录的指针。
在这里插入图片描述当一个线程想要获得某个对象的锁时,假如看到锁标记位为00,那么就知道他是轻量级锁,这是线程会在自己的虚拟机栈中开辟一块空间称为Lock Record。lock record 中存放的是对象头中mark word的副本和指向owner指针,线程通过CAS去尝试获取锁,一旦获得那么将会复制该对象头中的mark word副本到lock record中,并将owner指针指向该对象, 并且对象mark word的前30位指针会指向线程虚拟机栈中的lock record,这样就实现了线程和对象锁的绑定,他们就互相知道了对方的存在。
在这里插入图片描述如果现在处于轻量级锁并且有一个线程正在占用锁,另外一个线程想要获取锁,那么这个线程就会自旋,等待锁释放。
在这里插入图片描述如果自旋等待的锁的线程超过一个,那么就会升级重量级锁。
在这里插入图片描述

4、重量级锁

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值