Java对象头部与synchronized原理与优化
Posted oahaijgnahz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java对象头部与synchronized原理与优化相关的知识,希望对你有一定的参考价值。
文章目录
一、Java对象头部
Java对象头部主要包含Mark Word和类型指针。
HotSpot虚拟机的对象头(Object Header)包括两部分信息,第一部分用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,称为“Mark Word”。
这个对象头在32位的存储空间中,根据锁状态不同或者GC状态不同分成上图中的5种状态。
二、偏向锁与轻量级锁
从上图中总结对象锁优化的相关内容:
- 在目前的Java版本中,偏向锁是默认开启的,是否偏向的标识位为1。偏向锁的本质就是无锁,即在线程没有争抢的情况下,对象头记录线程ID,持有对象锁的线程栈帧中的Lock record记录空的Displaced Mark Word(退出同步块时对应删除)。要注意的是偏向过的锁,上一个线程退出后其线程ID还保留着,这样同一线程的多次访问不会受阻。但当不同线程ID的线程请求这个偏向锁时,会发现线程ID不同,则会去使用一次CAS操作改变对象头中的信息来获取这个对象的锁,成功就进入同步代码块执行,如果此操作失败说明对象发生了线程间竞争。则此对象会升级成轻量级锁。
- 轻量级锁定时,各个线程都是通过一定次数的CAS操作来争抢对象锁(修改Mark Word),如果对象被锁定则对象头中会保存持有该对象锁的线程指针(指向对应线程Lock record中的Displaced Mark Word),锁标志位为01。
- 当轻量级锁CAS修改Mark Word失败超过设定的次数,仍未抢到锁,则对象锁升级为重量级锁,线程进入阻塞。每个对象有一个monitor,线程执行monitorenter尝试获取对象锁,直至执行到monitorexit释放monitor(或者wait释放锁,notify唤醒继续争抢锁)。
以上是关于Java对象头部与synchronized原理与优化的主要内容,如果未能解决你的问题,请参考以下文章
synchronized的实现原理与应用&Java对象的内存布局
Java多线程 synchronized 锁方法和块使用详解 锁竞争本质原理 只与锁对象有关与位置无关