前言
在学习 synchronized 锁的发展史时,我们知道了一段“佳话”:
-
在 jdk1.5 时代, 大神级程序员 Doug Lea 开发出了 ReentrantLock, 其性能远远高于当时通过调用 Linux 内核互斥锁实现的 synchronized 锁。一时风光无两,广大程序员趋之若鹜。
-
在 jdk1.6 以后, synchronized 锁借鉴了 Doug Lea 的锁设计思想,对 synchronized 锁的实现进行了优化。
关于锁的状态
在学习 ReentrantLock 时,我们就接触过 AbstractQueuedSynchronizer 类。我们发现 AQS 使用了成员变量 state 来标识同步状态,也可以简单理解为锁的状态。
synchronized 锁显然也应该有这样一个表示锁状态的标识,但是这个标识存储在哪里呢?带着这个疑问,我们需要去查阅“相关资料”。
查阅资料
学习原理最靠谱的方式,一种是阅读“官方指南”,另一种则是阅读“开源代码”。
但是我们常用的 Oracle JDK 不开源啊,也找不到 synchronized 锁的实现文档啊?别担心!
OpenJDK 和 Oracle Java 如此相似,因此我们可以学习 OpenJDK 来掌握 Java 底层原理。
Hotspot here 是 JVM 虚拟机的一个重要实现。在文档中,可以看它的 术语表 链接:
术语表:A glossary of terms,从这个术语表中,我们可以得到一些概念解释。假如你要实现一款 JVM 商业产品,那么你也需要参考这些概念来进行实现。
下载 OpenJDK 源码
下面是我辛辛苦苦找来的下载地址:
OpenJDK7 download: here
OpenJDK8 download: here
如果链接失效了,欢迎留言。
术语:Object header
- 对象头主要由 mark word 和 klass pointer 两部分组成,如果是数组对象,则多出一个 数组长度。
其他细节待你去挖掘
对象头的 Bit Format
这段代码在 OpenJDK源码项目根目录\hotspot\src\share\vm\oops\markOop.hpp 这个文件中。
网上形形色色的图,追本溯源就是这段“官方注释”
使用 jol 查看
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
引入该依赖,然后使用
String value = ClassLayout.parseInstance(obj).toPrintable();
System.out.println(value);