(锁源码文件:bytecodeInterpreter.cpp)
问题:
1 偏向锁加锁前,加锁中,加锁后头变化
2 偏向锁升级轻量级锁,升级前,轻量锁,和轻量级锁完成对象头变化
结论:
1 偏向锁加锁前,对象头标识 101,没有保存线程ID
2 偏向锁加锁 ,对象头标识101,保存线程ID(1 当前线程中创建一个Lock Recode 2 所记录中的指针指向对象头)
3 偏向锁加锁后:对象头标识101,保存线程ID,如果同一个线程过来请求则对比线程ID,线程还是偏向锁
4偏向锁锁升级为轻量级锁前:对象头为101,存在线程ID ,第4步到5步骤偏向锁升级,中间会有偏向锁撤销,然后才升级轻量锁,这个会有性能损耗
5 轻量级锁加锁时候:对象头000,保存线程锁记录的指针(1 创建锁记录 2 所记录指针指向对象头 3对象头指针指向所记录 )
6 轻量级锁完成后:对象头001,无线程ID和所记录指针的保存
对于轻量级锁释放以后有新线程过来加锁:
1 生成一个无锁的markword(001)
2 将无锁的markword 替换掉线程中的所记录中的markword
3 用cas判断对象头中的markword标识的值和内存中生成的值(001)是否相同
4 如果相同,则将对象头中的指针指向栈帧中的所记录
5 如果不同,则可能是有新线程已经加锁,则当前锁需要膨胀为重量级锁
6 将对象头的标识为改成 00
测试代码:
package com.test;//package com.test; import org.openjdk.jol.info.ClassLayout; import java.util.concurrent.locks.LockSupport; /** * Hello world! *-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -XX:-UseCompressedOops 指针压缩测试 * -Xms1g -Xmx1g -XX:+PrintGCDetails -XX:BiasedLockingStartupDelay=0 偏向延迟关闭参数 */ public class Test4 { static Thread t1=null; static Thread t2 = null; public static void main( String[] args ) throws InterruptedException { B b = new B(); t1 = new Thread(){ @Override public void run() { System.out.println( Thread.currentThread().getId()); System.out.println(ClassLayout.parseInstance(b).toPrintable()); synchronized (b){ System.out.println(ClassLayout.parseInstance(b).toPrintable()); } System.out.println(ClassLayout.parseInstance(b).toPrintable()); LockSupport.unpark(t2); } }; t2 = new Thread( ){ @Override public void run() { LockSupport.park(); System.out.println("线程2开始执行======"); System.out.println( Thread.currentThread().getId()); System.out.println(ClassLayout.parseInstance(b).toPrintable()); synchronized (b){ System.out.println(ClassLayout.parseInstance(b).toPrintable()); } System.out.println(ClassLayout.parseInstance(b).toPrintable()); } }; t1.start(); t2.start(); t1.join(); t2.join(); } }