java synchronized锁对象,java线程锁synchronized

  java synchronized锁对象,java线程锁synchronized

  00-1010前言1。hashcode是什么时候存储在对象头中的?2.hashcode存在后,会同步什么锁?3.如果锁状态是偏向的,那么hashcode重新计算时会发生什么?4.摘要

  

目录

今天的文章从下图开始,Java开发者应该很熟悉。

 

  我们都知道,无锁状态意味着对象头有存储hashcode的位置,而有偏锁状态没有存储hashcode的位置。今天我们就通过实现来验证这个问题:当锁状态为biased lock时,hashcode去哪了?

  先说结论:

  Jdk8偏置锁定默认开启,但可以延时通过:-xx 3360偏置锁定启动延时=0关闭延时。hashcode是懒加载的,调用HashCode方法后才会保存在对象头中。当对象头中没有hashcode时,对象头锁的状态为biased (biased,101,无线程id)。如果在同步代码块之前调用hashcode方法,那么对象头中会有hashCode,锁状态是无偏的(0.01)。此时执行同步代码块,锁直接是轻量锁(瘦锁,00)。如果hashcode在同步代码块中执行,锁就直接从偏置锁扩展到重量级锁。

  00-1010根据下图,我们知道hashcode不是在对象实例化后创建的,而是在调用默认的hashcode方法时放入对象头中。

  在第一次打印的对象头中,我们发现对象头中的标记字值十六进制是5,转换成二进制是101,下面的状态显示为biasable,即Biasable。注意区分Biasable和Biased: Biasable表示还没有同步锁,Biased表示有线程访问锁。

  Hashcode已经存在于第二个打印对象的头中,值为0x00000039a054a501,转换为二进制:111001101001001001001001000001,后三位为001,表示不能有偏,也就是说出现同步锁时不会有偏。这是真的吗?我们来验证一下!

  00-1010根据下图,我们可以清楚的看到,当已经有一个hashcode,然后执行同步代码,就会直接进入轻量锁。原因还是上面的结论。如果在有hashcode之后锁被设置为无偏的,那么肯定会直接到轻量级锁。

  00-1010前两种情况,锁定状态偏置。这时候锁状态偏了怎么办?会有锁升级吗?

  根据下图我们可以看到,当hashCode方法在一个synchronized代码块中时,锁直接升级为重量级锁。

  至于为什么直接升级为重量级锁而不是轻量级锁,这个原因不得而知。

  朱哥猜测,在没有线程竞争的情况下,将偏置锁升级到重量级锁所消耗的资源比轻量级锁消耗的要少。

  同时,欢迎知道原因的同学留言,也欢迎你说出你的猜想?说不定以后会按照你的方案优化呢!

  00-1010JDK8偏置锁定默认开启,但有延迟。可以通过参数关闭延迟:-xx 3360 biasedlocking startup delay=0。hashcode是懒加载的,调用HashCode方法后才会保存在对象头中。当对象头中没有hashcode时,对象头锁的状态为biased (biased,101,无线程id)。如果在同步代码块之前调用hashcode方法,那么对象头中会有hashCode,锁状态是无偏的(0.01)。此时执行同步代码块,锁直接是轻量锁(瘦锁,00)。如果hashcode在同步代码块中执行,锁就直接从偏置锁扩展到重量级锁。以上是java用synchronized biased lock面试后hashcode的地址细节。更多Java中带偏锁hashcode的地址信息,请关注热门IT的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: