synchronized加锁之如何查看对象头

最近学习java中多线程如何加锁保证线程安全,讲解的synchronized关键字,加锁操作,可以保证线程安全,但是对于加锁是如何就实现了线程安全还是一头雾水。不管是书上还是博客上讲的最多的就是,synchronized是给对象头枷锁,同一个对象加锁的线程同步互斥。

语法:(1).同步代码块;(2).同步方法。

但我连什么是对象头都不知道。

首先我们要知道java有哪些锁?
偏向锁,自旋锁,独占锁,共享锁,轻量级锁,重量级锁,公平锁,非公平锁。

这么多的锁,但是加锁锁的是什么?锁代码块?锁对象?
—锁对象头。
但什么是对象头?
java对象头由什么组成?
java对象由什么组成?
java对象头在哪存放着?
java对象在堆上开辟多大的内存?
—开辟内存是不是固定的?(不固定,否则不会出现内存泄漏)

首先对象都有哪些属性:
1.对象头(固定)
2.java对象的实例数据
3.数据对齐

我们首先来看一下synchronized这个内置锁加锁后在内存中中的布局是怎样的。
(1).首先需要配置以下idea的pom.xml文件的依赖资源:

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

(2).现在一个测试类来观察java对象的布局情况是怎样的:

public class lock {
    
    
    boolean f=true;
}

import org.openjdk.jol.info.ClassLayout;

public class Test {
    
    
     static lock l=new lock();
    public static void main(String[] args) {
    
    
        lockTest();
    }
    public static void lockTest(){
    
    
        synchronized (l) {
    
    
            System.out.println("jjj");
            System.out.println(l.hashCode());
            //打印16进制的hashCode
            System.out.println(Integer.toHexString(l.hashCode()));
        System.out.println(ClassLayout.parseInstance(l).toPrintable());
        }

    }
}

(3).运行结果显示:
在这里插入图片描述
所以什么是java对象头?
—就是对象的第一个部分,所有对象公共的部分。
java对象头由什么组成?
—openjdk官方文档上对象头由两部分组成:
1.mark word:
存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂 不考虑开启压缩指针的场景)中分别为32个和64个Bits。
2.clazz pointer/ Class Metadata Address

上图截图中后面的那些01比特根据位数划分,代表了堆对象的布局、类型、GC状态、同步状态和表示hashCode的基本信息。

synchronized关键字加锁后怎样用那些0、1比特位修改对象的锁状态的,我可能学不会了,我还是放弃吧.

扫描二维码关注公众号,回复: 12927266 查看本文章

猜你喜欢

转载自blog.csdn.net/m0_46551861/article/details/115128421