在实际开发中,往往需要考虑数据并发安全问题,比如秒杀业务场景、买票业务场景,都需要考虑并发,Java提供了Synchornize关键字来为我们解决了并发性问题.
本文讲解Synchornize关键字的工作原理
一、Java对象头和Monitor
JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。
jvm.png
实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分,还会包括数组的长度,内存按四字节对齐。
填充数据:虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在,仅仅为了字节对齐。
Java头对象是实现Synchornize关键字的基础,一般来说,Synchornize锁对象是存储在JAVA对象头里的,JVM采用2个字节来存储对象头(如果对象是一个数组,会分配3个字节,剩下的一个字节用来记录数组长度),主要结构由Mark Word和Class MetaData Address组成
meta.png
其中Mark Word在默认情况下存储着对象的HashCode、分代年龄、锁标记位等以下是32位JVM的Mark Word默认存储结构
basicMeta.png
由于对象头的信息是与对象自身定义的数据没有关系的额外存储成本,因此考虑到JVM的空间效率,Mark Word 被设计成为一个非固定的数据结构,以便存储更多有效的数据,它会根据对象本身的状态复用自己的存储空间,如32位JVM下,除了上述列出的Mark Word默认存储结构外,还有如下可能变化的结构
superMeta.png
其中轻量级锁和偏向锁是Java 6对 synchronized 锁进行优化后新增加的,稍后我们会简要分析。这里我们主要分析一下重量级锁也就是通常说sy