最近学习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比特位修改对象的锁状态的,我可能学不会了,我还是放弃吧.