文章目录

  • 第一次验证
  • 第二次验证
  • 总结

相关文章:
锁状态位之无锁
锁状态位之偏向锁
锁状态位之轻量级锁
锁状态位之重量级锁

第一次验证


我们创建一个对象,没有上锁,然后再上锁,来观察锁标识位:

由于只有一个线程加锁,没有产生,所以预期是加偏向锁

public class Test {public static void main(String[] args) throws InterruptedException {//TimeUnit.SECONDS.sleep(5);  代码很重要,先注释掉,后面需要放开Object o = new Object();System.out.println(ClassLayout.parseInstance(o).toPrintable());  //第一次打印,此时无锁synchronized (o){System.out.println(ClassLayout.parseInstance(o).toPrintable());  //第二次打印,此时有锁}}
}

执行结果:


java.lang.Object object internals:OFFSET  SIZE   TYPE DESCRIPTION                               VALUE0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)8     4        (object header)                           e5 01 f3 27 (11100101 00000001 11110011 00100111) (670237157)12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes totaljava.lang.Object object internals:OFFSET  SIZE   TYPE DESCRIPTION                               VALUE0     4        (object header)                           88 f8 98 02 (10001000 11111000 10011000 00000010) (43579528)4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)8     4        (object header)                           e5 01 f3 27 (11100101 00000001 11110011 00100111) (670237157)12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes totalProcess finished with exit code 0

分析:

第一条是001无锁的,和锁状态位之无锁中第一章节内容相同,主要看第二条打印:

注意字节是反序的:88 f8 98 02 (10001000第四个字节 11111000第三个字节 10011000第二个字节 00000010第一个字节)

我们发现第二条打印结果是轻量级锁,不是预期的偏向锁

那么为什么呢?
虽然默认开启偏向锁,但JVM会延迟去启动偏向锁,延迟大约三四秒,此时对于系统的前几秒来说,等价于没有开启偏向锁,解决方案有2种:

  • 加sleep 5s再试,放开代码中的语句块

    TimeUnit.SECONDS.sleep(5);
    
  • 关闭延迟开启偏向锁
    -XX:BiasedLockingStartupDelay=0

对于第二条语句来说,等价于 无锁 ->加轻量级锁(单线程加锁,低竞争度)

第二次验证

加了延迟后,对于第二条语句来说,等价于 无锁 ->延迟3后启动偏向锁(偏向线程ID为空) ->偏向锁,设置偏向线程ID为当前线程id


java.lang.Object object internals:OFFSET  SIZE   TYPE DESCRIPTION                               VALUE0     4        (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)8     4        (object header)                           e5 21 f3 27 (11100101 00100001 11110011 00100111) (670245349)12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes totaljava.lang.Object object internals:OFFSET  SIZE   TYPE DESCRIPTION                               VALUE0     4        (object header)                           05 a8 5c 02 (00000101 10101000 01011100 00000010) (39626757)4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)8     4        (object header)                           e5 21 f3 27 (11100101 00100001 11110011 00100111) (670245349)12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes totalProcess finished with exit code 0

第一条显示偏向锁,但是偏向线程ID为空

jdk1.8时,默认开启偏向锁,创建一个对象的话(在真正开启偏向锁之后才创建的对象), 对象会是可偏向状态,即锁的标识显示是偏向锁,但是偏向线程ID为空,等到后续真的发生需要加偏向锁时,会仅修改偏向线程ID即可。

第二条显示偏向锁,偏向线程ID为当前线程id

总结

对于单线程,低竞争度的锁来说,不是一定加轻量级锁,而是偏向锁的+线程id 来过度的,当然,需要jvm一定时间去开启,需要等待几秒钟

参考:
《禁止延迟开启偏向锁jvm参数》

【jvm jdk】锁状态位之偏向锁相关推荐

  1. JVM内部锁升级过程(偏向锁,轻量级锁,重量级锁)

    目录 对象在内存中是如何布局的 如何查看对象在内存中的布局 markword数据结构 加锁后发生了什么 偏向锁 什么是偏向锁 偏向锁定时hashCode 哪去了? 为什么需要偏向锁 为什么从JDK15 ...

  2. 轻量级锁_Java高级架构师-Java锁的升级策略 偏向锁 轻量级锁 重量级锁

    欢迎关注头条号:Java小野猫 这三种锁是指锁的状态,并且是专门针对Synchronized关键字.JDK 1.6 为了减少"重量级锁"的性能消耗,引入了"偏向锁&quo ...

  3. 锁升级过程(偏向锁/轻量级锁/重量级锁)

    锁的前置知识 如果想要透彻的理解java锁的来龙去脉,需要先了解锁的基础知识:锁的类型.java线程阻塞的代价.Markword. 锁的类型 锁从宏观上分类,分为悲观锁与乐观锁. 乐观锁 乐观锁是一种 ...

  4. 偏向锁、轻量级锁、重量级锁加锁过程即锁升级膨胀过程

    偏向锁.轻量级锁.重量级锁加锁过程即锁升级膨胀过程 synchronized 偏向锁 为什么要引入偏向锁 偏向锁加锁过程 线程获取到锁对象的偏向锁之后,执行完同步代码块之后,会释放这个偏向锁吗 使用了 ...

  5. 【Java 并发编程】线程锁机制 ( 锁的四种状态 | 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 | 锁竞争 | 锁升级 )

    文章目录 一.悲观锁示例 ( ReentrantLock ) 二.重量级锁弊端 三.锁的四种状态 ( 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 ) 四.锁的四种状态之间的转换 ( 无锁状态 - ...

  6. JVM系列之:对象的锁状态和同步

    文章目录 简介 java对象头 java中锁状态的变化 偏向锁biased locking 轻量级锁thin lock 重量级锁 三种锁状态的不同 简介 锁和同步是java多线程编程中非常常见的使用场 ...

  7. 难搞的偏向锁终于要被Java移除了

    [文章来源][公众号:日拱一兵] 背 景 在 JDK1.5 之前,面对 Java 并发问题, synchronized 是一招鲜的解决方案: 普通同步方法,锁上当前实例对象 静态同步方法,锁上当前类 ...

  8. 在Java 17中偏向锁可算是废了

    与优秀的人在一起,自己也会优秀起来 高质量技术交流群,您还没加入吗? 赶紧点击加入我们,享受一起成长的快乐! 背景 在 JDK1.5 之前,面对 Java 并发问题, synchronized 是一招 ...

  9. 在Java 17中偏向锁可算废了

    背景 在 JDK1.5 之前,面对 Java 并发问题, synchronized 是一招鲜的解决方案: 普通同步方法,锁上当前实例对象 静态同步方法,锁上当前类 Class 对象 同步块,锁上括号里 ...

  10. 锁记——偏向锁注定过不好这一生

    背景 在 JDK1.5 之前,面对 Java 并发问题, synchronized 是一招鲜的解决方案: 普通同步方法,锁上当前实例对象 静态同步方法,锁上当前类 Class 对象 同步块,锁上括号里 ...

最新文章

  1. 使用amap-js引入高德地图AMap及其UI组件AMapUI
  2. 小学计算机课5年级第一课,人教版(2015)小学信息技术 五年级下册 第1课 录制声音真轻松 教案...
  3. 面试题系列(8):什么叫优雅降级和渐进增强?
  4. Linux常用命令(第二版) --帮助命令
  5. 信息学奥赛一本通(1068:与指定数字相同的数的个数)
  6. 请问孩子厌学的话该怎么办?
  7. TeamViewer——Ubuntu系统上的安装和卸载
  8. AjaxPro.NET实现TextBox智能获取服务端数据功能(Asp.net 2.0)(示例代码下载)
  9. OpenCV人工智能图像处理学习笔记 第4章 线段文字绘制
  10. 使用SSH连接linux服务器重启Tomcat服务
  11. visio连接线设置
  12. 无线局域网中RADIUS协议原理与实现
  13. 光纤通道网络FC vs 以太网光纤通道FCoE
  14. Python周刊518期
  15. 命令行重启Mysql
  16. [Baltic2008]Mafia
  17. Linux系统病毒防治
  18. [2017.02.06] 阅读《Effective Morden C++》
  19. EUL(end user layer)是什么 转自:专注 Oracle EBS
  20. Modbus通讯协议从一窍不通到原来如此

热门文章

  1. visual studio设置背景颜色为眼睛保护色
  2. 内网穿透什么意思?内网穿透基础知识原理内网穿透服务器搭建可以干嘛服务器端口映射无需公网IP教程方法
  3. STM32+W5500网络通信
  4. W5500调试的部分问题和注意点
  5. mysql中添加外键语句_数据库语句怎么加外键
  6. 运维 --- Nginx高级功能介绍
  7. sku mysql_MySQL-THINKPHP 商城系统二 商品模块的展示
  8. javashop7.15大型多店铺商城源码 java多店铺商 城系统b2b2c
  9. js头像裁剪实现——canvas+Jcrop+jQuery
  10. 为啥vb被计算机二级取消,计算机二级vb考试是不是今年最后一年