Synchronize 偏向锁,轻量级锁升级和撤销过程,对象头的变化

(锁源码文件: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();
 
    }
 
}
View Code
 最终打印结果:
    
com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


线程2开始执行======
13
com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           05 b0 93 1e (00000101 10110000 10010011 00011110) (512995333)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           10 f3 c3 1f (00010000 11110011 11000011 00011111) (532935440)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


com.test.B object internals:
OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           05 c2 00 f8 (00000101 11000010 00000000 11111000) (-134168059)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
 
 
 
 
原文地址:https://www.cnblogs.com/lean-blog/p/13719422.html