AI 怎么说
当我问deepseek,synchronized的锁升级过程,


一探究竟
它提到可以用jol来查看对象头,很久以前用过这个:如何查看一个java对象的大小 , 那么是否有更详细的代码能演示这个过程呢? 说干就干:
引入jol依赖:
// https://mvnrepository.com/artifact/org.openjdk.jol/jol-core
implementation group: 'org.openjdk.jol', name: 'jol-core', version: '0.17'
public static void main(String[] args) throws InterruptedException {
System.out.println(VM.current().details());
// by default 5 seconds initial delay for biased locking
Thread.sleep(1000 * 10);
final A a = new A();
ClassLayout layout = ClassLayout.parseInstance(a);
System.out.println("**** Fresh object");
System.out.println(layout.toPrintable());
// biased locking demo
System.out.println("################### biased locking demo ###################");
synchronized (a) {
System.out.println("**** With the lock");
System.out.println(layout.toPrintable());
}
System.out.println("**** After the lock");
System.out.println(layout.toPrintable());
// Synchronized locks upgrades
// free -> biased( one thread enter locking) -> lightwieght (different thread , while time split it out) -> heavyweight mutex
// lightweight locking demo
System.out.println("################### lightweight locking demo ###################");
A a2 = new A();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a2) {
System.out.println("**** lightweight locking With the lock - Thread1 ");
System.out.println(ClassLayout.parseInstance(a2).toPrintable());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
// sleep much longer.
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a2) {
System.out.println("**** lightweight locking With the lock - Thread2 ");
System.out.println(ClassLayout.parseInstance(a2).toPrintable());
}
}
}).start();
Thread.sleep(1000 * 6);
System.out.println("################### heavyweight locking demo ###################");
A a3 = new A();
ExecutorService es = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
es.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a3) {
System.out.println("**** heavyweight locking With the lock - " + Thread.currentThread().getName());
System.out.println(ClassLayout.parseInstance(a3).toPrintable());
}
}
});
}
es.shutdown();
es.awaitTermination(1, TimeUnit.MINUTES);
// final tasks
// wait all done
Thread.sleep(1000 * 10);
}
在上面的代码中分别演示了从free -> biased locking -> light weight locking -> heavyweight locking. 查看输出可以进一步验证:
1、无锁:biasable 表示
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
2、偏向锁, 单线程的多次获取:biased 表示
################### biased locking demo ###################
**** With the lock
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d09abb805 (biased: 0x000000008b426aee; epoch: 0; age: 0)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**** After the lock
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d09abb805 (biased: 0x000000008b426aee; epoch: 0; age: 0)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
3、轻度锁,多线程的错开时间使用,thin lock 表示
################### lightweight locking demo ###################
**** lightweight locking With the lock - Thread1
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d30252005 (biased: 0x000000008b4c0948; epoch: 0; age: 0)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**** lightweight locking With the lock - Thread2
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000005a776fef68 (thin lock: 0x0000005a776fef68)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
4、重度锁,高竞争,fat lock 表示
################### heavyweight locking demo ###################
**** heavyweight locking With the lock - pool-1-thread-7
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d2dc624da (fat lock: 0x0000022d2dc624da)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**** heavyweight locking With the lock - pool-1-thread-6
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d2dc624da (fat lock: 0x0000022d2dc624da)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
**** heavyweight locking With the lock - pool-1-thread-4
Test$A object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000022d2dc624da (fat lock: 0x0000022d2dc624da)
8 4 (object header: class) 0xf80155ab
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total