原创

synchronized原理

synchronized是java提供的同步锁,采用监视器(也叫管程)实现同步,监视器实现类是jvm里面的objectMonitor.cpp,当锁定的对象锁状态为010时,会创建objectMonitor对象

java对象头存储模板:(java8 64位机器 默认开启指针压缩情况)

|--------------------------------------------------------------------------------------------------------------|--------------------|
|                                            Object Header (96 bits)                                           |        State       |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                  Mark Word (64 bits)                           |    Klass Word (32 bits)     |                    |
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| unused:25 | identity_hashcode:31 | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Normal       |001 无锁
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
| thread:54 |       epoch:2        | cms_free:1 | age:4 | biased_lock:1 | lock:2 |    OOP to metadata object   |       Biased       |101偏向锁
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                         ptr_to_lock_record                            | lock:2 |    OOP to metadata object   | Lightweight Locked |000 轻量级锁
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                     ptr_to_heavyweight_monitor                        | lock:2 |    OOP to metadata object   | Heavyweight Locked |010 重量级锁
|--------------------------------------------------------------------------------|-----------------------------|--------------------|
|                                                                       | lock:2 |    OOP to metadata object   |    Marked for GC   |011 GC标记
|--------------------------------------------------------------------------------|-----------------------------|--------------------|

锁升级过程:

1.没有synchronized锁定时,对象头锁状态是无锁状态001

2.有synchronized关键字,只有一个线程,没有遇见线程竞争时是轻量级锁状态000

3.当遇见线程竞争,自旋10次未获取到锁,升级为重量级锁010,此时创建管程对象(监视器),对象头指向管程对象,管程对象管理线程

备注:偏向锁状态101,当设置-XX:BiasedLockingStartupDelay=0时会出现,遇见线程竞争会升级为重量级锁

	private static final Object OBJECT = new Object();

	public static void main(String[] args) throws InterruptedException {
		System.out.println(VM.current().details());
		//-XX:BiasedLockingStartupDelay=4
		System.out.println("------没有加synchronized:" + Thread.currentThread().getName());
		System.out.println(ClassLayout.parseInstance(OBJECT).toPrintable());
		System.out.println("------单个线程:" + Thread.currentThread().getName());
		printObjectHeader();
		System.out.println("------多个线程:" + Thread.currentThread().getName());
		Thread t1 = new Thread(SynchronizedDemo::printObjectHeader, "t1");
		Thread t2 = new Thread(SynchronizedDemo::printObjectHeader, "t2");
		t1.start();
		t2.start();
		for (; ; ) {
		}
	}

	private static void printObjectHeader() {
		synchronized (OBJECT) {
			System.out.println("当前线程:" + Thread.currentThread().getName());
			System.out.println(ClassLayout.parseInstance(OBJECT).toPrintable());
		}
	}

//执行程序,输出以下内容:
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

------没有加synchronized:main
java.lang.Object 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)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

------单个线程:main
当前线程:main
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           08 79 9d 33 (00001000 01111001 10011101 00110011) (865958152)
      4     4        (object header)                           36 7f 00 00 (00110110 01111111 00000000 00000000) (32566)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

------多个线程:main
当前线程:t1
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           8a 5e 00 f0 (10001010 01011110 00000000 11110000) (-268411254)
      4     4        (object header)                           35 7f 00 00 (00110101 01111111 00000000 00000000) (32565)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

当前线程:t2
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           8a 5e 00 f0 (10001010 01011110 00000000 11110000) (-268411254)
      4     4        (object header)                           35 7f 00 00 (00110101 01111111 00000000 00000000) (32565)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
正文到此结束