首页 > 其他分享 >偏向锁 10 连问,被问懵圈了。。

偏向锁 10 连问,被问懵圈了。。

时间:2023-02-22 10:55:49浏览次数:35  
标签:10 连问 批量 对象 lock record 线程 问懵圈 偏向

前言

对于Hotpot JVM中的偏向锁,大部分开发者都比较熟悉或者至少听说过。那我们用下面10个关于偏向锁的进阶问题,检验一下自己离精通还有多远。

  • 如何判断当前锁对象为偏向锁
  • 偏向锁如何判断锁重入
  • 当代码运行至synchronized修饰的代码块时,符合什么条件才会尝试获取偏向锁
  • 线程进入偏向锁后,会不会创建lock record
  • 偏向锁膨胀后,lock record有什么变化
  • 如何判断当前持有锁的线程已经因为批量重偏向,而被撤销了偏向锁
  • 批量撤销和批量重偏向的触发条件是什么
  • 批量重偏向后,lock record和锁对象有什么变化
  • 批量撤销后,lock record和锁对象有什么变化
  • 批量撤销/重偏向后,新创建的锁对象,是否支持偏向锁

看了上面的问题,如果是胸有成竹,那就可以跳过这篇文章了。如果一脸问号,这篇文章应该对你有所帮助。

名词解释

首先明确下文章中用到的名词,因为不同人可能叫法不一样。

对象头,Java对象在堆中存储时,会按照对象头加实例数据的结构来存储。这篇文章只讲锁,所以一般是指对象头中的Markword部分。

klass对象,jvm在加载类之后,会在堆内存中生成该类的对象,就是我们代码中this.getClass()获取的对象。

锁对象, synchronized指定的锁对象。对于普通方法,这个对象默认是this指针。对于静态方法,锁对象是堆里的class对象。

Lock record,进入synchronized时在线程栈中生成的锁记录,对这个不熟悉的可以百度一下或看一下《深入java虚拟机》这本书

锁膨胀,hotspot中从轻量级锁升级成重量级锁称之为膨胀,为了便于理解,通常把偏向锁升级成轻量级锁也称为膨胀。

问题解析

问题1:如何判断当前锁对象为偏向锁

这个问题比较简单,一般了解过对象头或者偏向锁的都比较熟悉。当锁对象为偏向锁时,Markword的偏向锁标识位为1,锁标识位为01。即markword的最后3位为101。

问题2:偏向锁如何判断锁重入

接上面问题的Markword结构,当已经有线程获取到偏向锁,它的id就会填到markword中的线程id中。重入时线程只要检查thread id里存的是否就是自己线程的id就可以了。

问题3:符合什么条件才会尝试获取偏向锁

首先,hotspot中通过参数UseBiasedLocking控制是否启用偏向锁,不设置时默认是启用的。如果想要禁用偏向锁,可以在启动参数中添加-XX:-UseBiasedLocking。

是不是这样回答这个问题就结束了呢?答案是否定的。hotspot还有一个延迟偏向的概念,就是在jvm启动的时候是有一个延迟时间,过了这段时间后偏向锁才开始启用。这个延迟时间通过启动参数BiasedLockingStartupDelay来设置,默认为4秒。那延迟的目的是什么呢?hotspot的解释是在jvm启动过程中,内部有多个逻辑会用到锁,比如类加载。如果一开始就启用偏向锁,就导致频繁的撤销偏向锁,偏向锁的撤销需要在安全点执行,这样有可能影响jvm启动的速度。

满足上面2个条件之后,是不是就愉快的进入偏向锁了呢,其实还要经过2关。

第三个条件就是锁对象没有膨胀,如果锁对象已经膨胀成轻量级锁了,那就不会再走偏向锁了。这就是经常说的锁只支持升级,不支持降级。轻量级锁的markword如下:

最后,如果锁对象对应的class发生了批量撤销的动作,也不会再进入偏向锁了。比如有10个锁对象lockobj0..lockobj9,他们都是LockObj类的实例,如果发生偏向锁的批量撤销,那在这10个锁对象上的抢锁操作都不会再走偏向锁逻辑。

问题4:线程进入偏向锁后,会不会创建lock record

了解轻量级锁逻辑的都知道,轻量级锁加锁后,锁对象会保存lock record的引用,关系如下:

那偏向锁有没有呢?答案是有的。其实轻量级锁的这个lock record在运行至synchronized的时候就创建了,这个时候jvm还不知道具体使用的是偏向锁还是轻量级锁,偏向锁和轻量级锁用的是同一个lock record。偏向锁的时候,对象头里没有lock record的指针。

但是,我们再深挖一层,是不是每次都会创建?答案是否定的。比如在同一个方法中,对同一个锁对象的重入,就不会再次创建lock record,比如下面的代码(虽然不会有人这么写代码

标签:10,连问,批量,对象,lock,record,线程,问懵圈,偏向
From: https://www.cnblogs.com/javastack/p/17143585.html

相关文章

  • GAMES101-HW1-个人遇到的一些问题(1)
    1.环境配置参考:https://blog.csdn.net/euphorias/article/details/120768828这里只简述部分内容:VS2019需要在资源管理器中右键项目-属性-(在对应配置,如Debug下)(1).VC+......
  • 频率信号转电压或电流信号隔离变送器0-1KHz / 0-5KHz / 0-10KHz转0-2.5V/0-5V/0-10V
    主要特性:​>>精度等级:0.2级>>全量程内极高的线性度(非线性度<0.1%)>>辅助电源/信号输入/信号输出:2500VDC 三隔离>>辅助电源:5VDC,12VDC,24VDC等单电源供电>>输入频率......
  • [vncserver] Warning: VM-8-10-ubuntu:1 is taken because of /tmp/.X11-unix/X1
    环境Ubuntu18问题描述解决方法将提示的文件删掉,并重新运行rmif[文件名]如果出现灰屏、黑×,并提示unencrytedconnection解决方法......
  • [OS] 游戏党狂喜 AtlasOS v0.5.2 Win10高性能精简版
    [OS]游戏党狂喜AtlasOSv0.5.2Win10高性能精简版此文章引用地址:https://www.hybase.com/xitong/windows/2375.html哈喽,黑域小伙伴,AtlasOS可能大家比较陌生,但对于爱......
  • [OS] 这系统只为游戏而生 ReviOS游戏定制版 Win11/Win10
    [OS]这系统只为游戏而生ReviOS游戏定制版Win11/Win10此文章引用地址:https://www.hybase.com/xitong/windows/2679.html哈喽,黑域小伙伴,针对游戏玩家而定制的系统版本......
  • NLP预训练模型 | 按时间线整理10种常见的预训练模型
    https://zhuanlan.zhihu.com/p/210077100 最近在学习NLP常见的预训练模型,做一下整理和对比,按照时间线主要有:ELMO2018.3华盛顿大学 论文 / 代码GPT2018.06Open......
  • 10分钟学会使用 Loki 日志聚合系统
    Loki是一个由GrafanaLabs开发的开源日志聚合系统,旨在为云原生架构提供高效的日志处理解决方案。Loki通过使用类似Prometheus的标签索引机制来存储和查询日志数据,这使......
  • PAT Basic 1002. 写出这个数
    PATBasic1002.写出这个数1.题目描述:读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。2.输入格式:每个测试输入包含1个测试用例,即给出自然数......
  • pat1010
    题不难,但是代码有一个结果报错,猜测可能如果输入0000234的话,可能会输出-1?先标记一下看看别人的#include<iostream>#include<stdio.h>usingnamespacestd;intmain(......
  • pat1009
    算法笔记原题#include<iostream>#include<stdio.h>usingnamespacestd;intmain(){intnum=0;charans[90][90];while(scanf("%s",ans[num])!=EO......