以下内容均引自《深入理解 JVM 》第二版,周志明先生著。
简单地介绍了对象的内存布局后,我们把话题返回到轻量级锁的执行过程上。在代码进入同步块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录( Lock record )的空间,用于存储锁对象目前的 Mark Word 的拷贝(官方把这份拷贝加了一个 Displaced 前缀,即 Displaced Mark Word ),这时候线程堆栈与对象头的状态如图 13-3 所示。 然后,虚拟机将使用 CAS 操作尝试将对象的 Mark Word 更新为指向 Lock record 的指针。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象 Mark Word 的锁标志位( Mark Word 的最后 2bit )将转变为“00”,即表示此对象处于轻量级锁定状态,这时候线程堆栈与对象头的状态如图 13-4 所示。
上面这个引用出自『 13.3.4 轻量级锁 』
如果读者读懂了前面轻量级锁中关于对象头 Mark Word 与线程之间的操作过程,那偏向锁的原理理解起来就会很简单。假设当前虚拟机启用了偏向锁(启用参数-XX:+ UseBiased Locking,这是 JDK1.6 的默认值),那么,当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的标志位设为“01”,即偏向模式。同时使用 CAS 操作把获取到这个锁的线程的 DD 记录在对象的 Mark Word 之中,如果 CAS 操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作(例如 Locking 、Unlocking 及对 Mark Word 的 Update 等)
这一段出自『 13.3.5 偏向锁 』
一个即将第一次因为 synchronized 被上锁的对象,对象头的末两个 bit 是 01
(1)然后,虚拟机将使用 CAS 操作尝试将对象的 Mark Word 更新为指向 Lock record 的指针。
(2)那么,当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的标志位设为“01”(第一次被获取的话不是自然而然就是 01 么,为何还要特别设置),即偏向模式。同时使用 CAS 操作把获取到这个锁的线程的 DD 记录在对象的 Mark Word 之中,
( 1 ) ( 2 ) 中有两个设置到对象头中的内容。。。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.