Java锁

Java传家宝:微信公众号(Java传家宝)、Java传家宝-B站Java传家宝-知乎Java传家宝-CSND


Java锁

​ 在Java中,锁按状态分可以分为无锁、偏向锁、轻量级锁、重量级锁,因为Java锁都基于对象的,所以Java对象的对象头含有专门记录锁状态的位置。

Java对象

​ 首先解析一下JAVA对象的内存结构,如图

JAVA对象内存结构
JAVA对象内存结构

实例数据类中真正存储的有效信息。就是在程序中类定义的各种类型的字段信息,包括父类继承的全部都存储在其中。

对其填充:并不是必然存在的,只起着占位符的作用。Hotspot VM要求对象的起始地址必须是8字节的整数倍。即要求Java对象必须是8字节的整数倍。

对象头:这部分与锁相关,本节细说,他一共可分为三部分,长度根据处理器是32位还是64位决定:

对象头结构
对象头结构
长度内容说明
32/64bitMark WordHashCode、锁状态、GC年龄等
32/64bitClass Metadata Address存储指向对象类型的指针
32/64bitArray Length数组长度(如果是数组的话)

其中Mark Word记录的内容会根据锁的状态而改变

锁状态标志位(2bit)存储内容
无锁01GC年龄,HashCode
偏向锁01偏向ID、偏向时间戳、GC年龄
轻量级锁00指向栈中锁记录的指针
重量级锁10指向重量级锁(互斥量)的指针
GC标记11

偏向锁

​ 偏向锁用于消除数据无竞争情况下的同步操作,提高程序性能。

没有线程竞争,任何时刻都只有一个线程获取该锁

具体过程表现为:

  • 锁对象 第一次被线程获取。
  • 虚拟机将锁对象的 标志为置为01,通过使用CAS操作将该 线程ID记录在锁对象的Mark Word中。
  • CAS操作成功,那么此线程在每次进入与该对象锁相关的同步块时, 可不进行同步操作
  • 当有 别的线程获取该对象锁时,偏向模式宣告结束。根据当前锁对象的状态, 撤销偏向或者锁升级为 轻量级锁
偏向锁过程
偏向锁过程

轻量级锁

​ 轻量级锁的目的在于没有多线程竞争的前提下,减少重量级锁使用操作系统互斥量(mutex)产生的性能消耗。

多个线程在不同时段获取同⼀把锁,即不存在锁竞争的情况,也就没有线程阻塞

具体过程表现为:

  • 首先在栈帧建立一个 Lock Record锁记录
  • 将锁对象的Mark Word的拷贝 Displaced Mark Word存储在Lock Record中
  • 然后通过CAS操作将 锁对象的Mark Word更新为栈帧中Lock Record的指针地址
    • 成功,将锁对象标志置为 00,表示轻量级锁状态
    • 失败,检查当前锁对象的Mark Word是否已经指向栈帧
      • 是,可直接进入同步块
      • 否,说明别的线程来抢占改锁了,将其升级为重量级锁
轻量级锁过程
轻量级锁过程

重量级锁

​ 重量级锁依赖于操作系统的互斥量(mutex) 实现的,⽽操作系统中线程间状态的转换需要用户态和内核态之间转换,耗时,所以重量级锁效率很低,因为不会使用CAS自旋,阻塞的线程不会消耗 CPU

具体过程表现为:

  • 当一个线程获取锁时,如果该锁已经被获取了
  • 那么该线程就进入 竞争队列,并挂起
  • 当锁对象释放后,会从竞争队列或 候选队列中随机选取一个唤醒,作为 假定继承人
  • 假定继承人采用CAS自旋获取锁
重量级锁抢占过程
重量级锁抢占过程

锁升级流程

​ 最后总结一下锁升级的流程

锁升级流程
锁升级流程
  • 线程第一次获取对象锁, 检查对象头是否存放自己的线程ID
  • ,说明处于偏向状态, 偏向锁,继续执行
  • 不是就通知对应线程阻塞,同时在自己的栈帧中拷贝对象头的内容到Lock Record
  • 通过CAS抢占修改对象头的内容为自己栈帧中的Lock Record地址, 升级为轻量级锁
  • 成功的线程继续执行, 失败的进入自旋
  • 自旋 成功,仍然为 轻量级锁
  • 自旋 失败,升级为 重量级锁,自身进入阻塞状态,等待执行完同步块的线程唤醒。
  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值