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
正文到此结束
- 本文标签: java
- 本文链接: https://codeis.run/article/synchronized-principle
- 版权声明: 本文由醒醒原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权