Java高级进阶多线程学习之路(三)偏向锁

​    想要理解synchronized的升级过程,首先我们来了解一个工具,他就是JOL(Java Object Layout),JOL如何使用呢,很简单,百度上一大堆,maven里引入类库就能使用,这里不再赘述。

有这样一个面试题,当你new一个对象的时候,他的内存布局是怎么样的?一看这个问题就有点懵,那么就来恶补一下基础知识吧。

分析一下问题,这个问题实际上是问我们这个对象在堆中占用的空间里面是怎么布局的,那么这个空间是由哪几项构成的呢,一共有四项构成:

1.markWord 标记 64系统 8个字节

2.Klass Pointer 类指针,指向属于哪个类的,比如new的一个T,那他就是   T.class 默认4个字节

3.Instance Data 成员变量

4.Padding 对齐 如果整个对象占有的字节数值不能被8整除,那就补上。好处是什么呢,我们的系统是64位的,一次处理8个字节就很爽如果是数组对象,那么他是五项,多了一个数组长度。

    所谓的synchronized 给对象上锁,他干了什么事情呢,我们来看一下。

    这里要说明一下图中synchronized锁的是对象,并不是代码块,大家不要搞错了。可以看到对象上锁之后markWord 变了,其他的没变,说明锁的信息是记录在markWord中的,那MarkWork中还记录了哪些信息呢,还有hashcode,GC的信息。下面我们来跟踪一下Markwork的修改过程,通过这个过程我们来理解synchronized进行了哪些优化。

    大家看到这里有个偏向锁,什么是偏向锁呢,简单说一下,因为在程序运行期间,多数情况下都是一个线程在工作,例如StringBuffer,Vector。没有并发使用自旋锁的意义不大,这个时候就诞生了偏向锁,偏向锁说白了就是偏向第一个来做操作的线程,比如上厕所,你是第一个人,那么你把自己的名字贴到门上,进去了,这时候如果其他人来了看到门上有名字了怎么办,没错就是自旋,在外面等着,如果人多到一定程度,场面hold不住了,管厕所的就会出来让大家排队,这就是升级到重量级锁了

    再看这个图里,如何从markword中看锁信息呢,先看后两位,图上已经画的很明白了,00是轻量级锁,10是重量级锁,11是被GC标记了,区分无锁态和偏向锁要看后三位,001代表无锁,101代表偏向锁

    那么再看我们刚刚那段代码的执行结果,这里大家可能会很疑惑,为什么锁信息显示的是轻量级锁 而不是偏向锁,这是因为偏向锁有延迟,他会在jvm启动四秒后启动,所以这段代码执行时,偏向锁还没有启动,那如何查看偏向锁呢,那他睡5秒不就行了吗,哈哈!

     这个图里我们让他睡了5秒,这时看未加锁之前他已经是偏向锁了,这个就是匿名偏向,加锁之后数字变了说明他把线程id给记录了下来。

你可能感兴趣的:(Java高级进阶多线程学习之路(三)偏向锁)