当前位置:首页 > 科技  > 软件

Java中的锁升级机制:偏向锁、轻量级锁和重量级锁

来源: 责编: 时间:2024-03-18 17:41:41 122观看
导读Monitor实现的锁属于重量级锁,你了解过锁升级吗?前面我们说了 synchronized 底层由monitor实现的,它那 synchronized 到底锁的是什么呢?随着 JDK 版本的升级,synchronized 又做出了哪些改变呢?“synchronized 性能很差”的

Monitor实现的锁属于重量级锁,你了解过锁升级吗?um428资讯网——每日最新资讯28at.com

前面我们说了  synchronized 底层由monitor实现的,它那 synchronized 到底锁的是什么呢?随着 JDK 版本的升级,synchronized 又做出了哪些改变呢?“synchronized 性能很差”的谣言真的存在吗?um428资讯网——每日最新资讯28at.com

在介绍以上内容之前,我们要先知道重量级锁概念。um428资讯网——每日最新资讯28at.com

重量级锁

当另外一个线程执行到同步块的时候,由于它没有对应 monitor 的所有权,就会被阻塞,此时控制权只能交给操作系统,也就会从 user mode 切换到 kernel mode, 由操作系统来负责线程间的调度和线程的状态变更, 这就需要频繁的在这两个模式下切换(上下文转换)。有点竞争就找内核的行为很不好,会引起很大的开销,所以大家都叫它重量级锁,自然效率也很低,这也就给很多小伙伴留下了一个印象 —— synchronized 关键字相比于其他同步机制性能不好,但其实不然。um428资讯网——每日最新资讯28at.com

  • Monitor实现的锁属于重量级锁,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。
  • 在JDK 1.6引入了两种新型锁机制:偏向锁和轻量级锁,它们的引入是为了解决在没有多线程竞争或基本没有竞争的场景下因使用传统锁机制带来的性能开销问题。

一、MarkWord

在JVM虚拟机中,对象在内存中存储的布局可分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

我们需要重点分析MarkWord对象头,因为Markword 是保存锁状态的关键,对象锁状态可以从偏向锁升级到轻量级锁,再升级到重量级锁,加上初始的无锁状态,可以理解为有 4 种状态。想在一个对象中表示这么多信息自然就要用位来存储。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

  • hashcode:25位的对象标识Hash码
  • age:对象分代年龄占4位
  • biased_lock:偏向锁标识,占1位 ,0表示没有开始偏向锁,1表示开启了偏向锁

thread:持有偏向锁的线程ID,占23位um428资讯网——每日最新资讯28at.com

  • epoch:偏向时间戳,占2位
  • ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针,占30位
  • ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针,占30位

我们可以通过lock的标识,来判断是哪一种锁的等级um428资讯网——每日最新资讯28at.com

  • 后三位是001表示无锁
  • 后三位是101表示偏向锁
  • 后两位是00表示轻量级锁
  • 后两位是10表示重量级锁

二、轻量级锁

在很多的情况下,在Java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步块中的代码。这种情况下,用重量级锁是没必要的。因此JVM引入了轻量级锁的概念。um428资讯网——每日最新资讯28at.com

如果 CPU 通过 CAS(后面会细讲,戳链接直达)就能处理好加锁/释放锁,这样就不会有上下文的切换。um428资讯网——每日最新资讯28at.com

但是当竞争很激烈,CAS 尝试再多也是浪费 CPU,权衡一下,不如升级成重量级锁,阻塞线程排队竞争,也就有了轻量级锁升级成重量级锁的过程。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

作为程序员的我们最喜欢用代码说话,贴心的 openjdk 官网提供了可以查看对象内存布局的工具 JOL (java object layout),我们直接通过 Maven 引入到项目中。um428资讯网——每日最新资讯28at.com

<dependency>      <groupId>org.openjdk.jol</groupId>      <artifactId>jol-core</artifactId>      <version>0.14</version>  </dependency>
public class SyncSample {    private static Object LOCK = new Object();    public static void main(String[] args) {        System.out.println("----------未进入同步块,MarkWord 为:----------");        System.out.println(ClassLayout.parseInstance(LOCK).toPrintable());        synchronized (LOCK) {            System.out.println("----------进入同步块,MarkWord 为:----------");            System.out.println(ClassLayout.parseInstance(LOCK).toPrintable());        }    }}

图片图片um428资讯网——每日最新资讯28at.com

2.1 加锁流程

1.在线程栈中创建一个Lock Record,将其obj字段指向锁对象。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

2.通过CAS指令将Lock Record的地址存储在对象头的mark word中(数据进行交换),如果对象处于无锁状态则修改成功,代表该线程获得了轻量级锁。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

3.如果是当前线程已经持有该锁了,代表这是一次锁重入。设置Lock Record第一部分为null,起到了一个重入计数器的作用。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

4.如果CAS修改失败,说明发生了竞争,需要膨胀为重量级锁。um428资讯网——每日最新资讯28at.com

2.2 解锁流程

1.遍历线程栈,找到所有obj字段等于当前锁对象的Lock Record。um428资讯网——每日最新资讯28at.com

2.如果Lock Record的Mark Word为null,代表这是一次重入,将obj设置为null后continue。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

3.如果Lock Record的 Mark Word不为null,则利用CAS指令将对象头的mark word恢复成为无锁状态。如果失败则膨胀为重量级锁。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

三、偏向锁

轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

可是多线程环境,也不可能只有同一个线程一直获取这个锁,其他线程也是要干活的,如果出现多个线程竞争的情况,就会有偏向锁升级的过程。um428资讯网——每日最新资讯28at.com

1.在线程栈中创建一个Lock Record,将其obj字段指向锁对象。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

2.通过CAS指令将Lock Record的线程id存储在对象头的mark word中,同时也设置偏向锁的标识为101,如果对象处于无锁状态则修改成功,代表该线程获得了偏向锁。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

3.如果是当前线程已经持有该锁了,代表这是一次锁重入。设置Lock Record第一部分为null,起到了一个重入计数器的作用。与轻量级锁不同的时,这里不会再次进行cas操作,只是判断对象头中的线程id是否是自己,因为缺少了cas操作,性能相对轻量级锁更好一些。um428资讯网——每日最新资讯28at.com

图片图片um428资讯网——每日最新资讯28at.com

思考:偏向锁可以绕过轻量级锁,直接升级到重量级锁吗?um428资讯网——每日最新资讯28at.com

图片um428资讯网——每日最新资讯28at.com

四、面试题

面试官:Monitor实现的锁属于重量级锁,你了解过锁升级吗?um428资讯网——每日最新资讯28at.com

Java中的synchronized有无锁(无锁就是没有对资源进行锁定,任何线程都可以尝试去修改它)、偏向锁、轻量级锁、重量级锁四种形式,偏向锁、轻量级锁、重量级锁分别对应了锁只被一个线程持有、不同线程交替持有锁、多线程竞争锁三种情况um428资讯网——每日最新资讯28at.com

锁别um428资讯网——每日最新资讯28at.com

描述um428资讯网——每日最新资讯28at.com

重量级锁um428资讯网——每日最新资讯28at.com

底层使用的Monitor实现,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。um428资讯网——每日最新资讯28at.com

轻量级锁um428资讯网——每日最新资讯28at.com

线程加锁的时间是错开的(也就是没有竞争),可以使用轻量级锁来优化。轻量级修改了对象头的锁标志,相对重量级锁性能提升很多。每次修改都是CAS操作,保证原子性um428资讯网——每日最新资讯28at.com

偏向锁um428资讯网——每日最新资讯28at.com

一段很长的时间内都只被一个线程使用锁,可以使用了偏向锁,在第一次获得锁时,会有一个CAS操作,之后该线程再获取锁,只需要判断mark  word中是否是自己的线程id即可,而不是开销相对较大的CAS命令um428资讯网——每日最新资讯28at.com


um428资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-77523-0.htmlJava中的锁升级机制:偏向锁、轻量级锁和重量级锁

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 面试官:SpringBoot如何优雅停机?

下一篇: CSS 实现居左到居右过渡变化的一些思路

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    旗舰机基本上使用的都是双曲面屏幕,这就让很多喜欢直屏的爱好者在苦等一款直屏旗舰,这次,你们等到了。据博主数码闲聊站带来的最新爆料称,Redmi下代旗舰K70 Pro和iQOO 12两款手
  • 石头智能洗地机A10 Plus体验:双向自清洁治好了我的懒癌

    石头智能洗地机A10 Plus体验:双向自清洁治好了我的懒癌

    一、前言和介绍专为家庭请假懒人而生的石头科技在近日又带来了自己的全新旗舰新品,石头智能洗地机A10 Plus。从这个产品名上就不难看出,这次石头推出的并不是常见的扫地机器
  • 微软邀请 Microsoft 365 商业用户,测试视频编辑器 Clipchamp

    微软邀请 Microsoft 365 商业用户,测试视频编辑器 Clipchamp

    8 月 1 日消息,微软近日宣布即将面向 Microsoft 365 商业用户,开放 Clipchamp 应用,邀请用户通过该应用来编辑视频。微软于 2021 年收购 Clipchamp,随后开始逐步整合到 Microsof
  • JVM优化:实战OutOfMemoryError异常

    JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 当家的盒马,加速谋生

    当家的盒马,加速谋生

    来源 | 价值星球Planet作者 | 归去来自己&ldquo;当家&rdquo;的盒马,开始加速谋生了。据盒马官微消息,盒马计划今年开放生鲜供应链,将其生鲜商品送往食堂。目前,盒马在上海已经与
  • 超级标准版旗舰!iQOO 11S全球首发iQOO超算独显芯片

    超级标准版旗舰!iQOO 11S全球首发iQOO超算独显芯片

    上半年已接近尾声,截至目前各大品牌旗下的顶级旗舰都已悉数亮相,而下半年即将推出的顶级旗舰已经成为了数码圈爆料的主流,其中就包括全新的iQOO 11S系
  •  首发天玑9200+ iQOO Neo8系列发布首销售价2299元起

    首发天玑9200+ iQOO Neo8系列发布首销售价2299元起

    2023年5月23日晚,iQOO Neo8系列正式发布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro强悍登场,限时售价3099元起;价位段最强性能手机iQOO Neo8同期上市
  • 质感不错!OPPO K11渲染图曝光:旗舰IMX890传感器首次下放

    质感不错!OPPO K11渲染图曝光:旗舰IMX890传感器首次下放

    一直以来,OPPO K系列机型都保持着较为均衡的产品体验,历来都是2K价位的明星机型,去年推出的OPPO K10和OPPO K10 Pro两款机型凭借各自的出色配置,堪称有
Top