线程学习记录-锁原理与对象头

锁原理与对象头

对象头

对象头是堆中对象的头结构,它由两个部分组成,mark wordklass word

mark word的简要介绍

mark word结构图示 如图所示:

  • mark word的大小为64bit,在对象的5种状态中(无锁,偏向锁,轻量级锁,重量级锁,GC标记),mark word的结构有所不同
  • 在 无锁 状态时,mark word的前56bit存储对象的hashcode信息。(前25bit为未使用,后31bit存储hashcode)
  • 在 偏向锁 状态时,mark word的前54bit存储获取锁的线程相关信息.
  • 在 轻量级锁 状态时,mark word的前62bit存储线程的栈的指针。
  • 在 重量级锁 状态时,markword的前62bit存储一个monitor对象信息。

klassword的简要介绍

  • klassword 的32位或者64位代表元数据的指针。
  • klassword的大小为64bit,如果开启了指针压缩,大小为32bit。

无锁态的对象,它的hashcode以及对象头信息

先上代码,这里我们使用了openjdk的jol包,可以看到对象以及jvm相关信息

     <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>

    public static void main(String[] args) throws InterruptedException {
        new JOLExample1().doHash();
        //jvm的信息
       // out.println(VM.current().details());

    }
    public void doHash(){
        Base  a=new Base();
        out.println("before hash");
        out.println(ClassLayout.parseInstance(a).toPrintable());
        out.println("jvm----------"+Integer.toHexString(a.hashCode()));
        out.println("after hash");
        out.println(ClassLayout.parseInstance(a).toPrintable());
    }
    

打印的无锁对象信息为

 

由于本机cpu采用小端模式,所以看到的hashcode在对象头中的存储顺序是高低位相反的。

延迟偏向锁以及偏向锁和轻量级锁的性能差异分析

如果一个锁不存在线程竞争,那么它是一个偏向锁。但是不同版本jdk,存在偏向锁延迟策略,所以不同版本jdk的偏向锁机制有所差异。

经测试,jdk8默认有4秒偏向延迟。jdk13默认关闭了偏向延迟,直接使用偏向锁。

我们通过代码分析下,对象在不同阶段的锁类型以及对应的运行时间。

public class CompareLock {

  static Base base=new Base();
  public static void main(String[] args) throws InterruptedException {
      out.println("before lock");
      out.println(ClassLayout.parseInstance(base).toPrintable());
      TimeUnit.SECONDS.sleep(1);
      testSpeed();
      out.println("after lock");
      out.println(ClassLayout.parseInstance(base).toPrintable());

  }

  public static void testSpeed() {
      long stard = System.currentTimeMillis();
      for (int i = 0; i < 100000000; i++) {
          synchronized (base) {
              if (i==0){
                  err.println("start locking  0");
                  out.println(ClassLayout.parseInstance(base).toPrintable());
              }
              if (i==200000){
                  err.println(" locking 200000");
                  out.println(ClassLayout.parseInstance(base).toPrintable());
              }
              if 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值