First test results
=====================main-monitor1无锁001=====================
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-monitor1轻量级锁00=====================
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) e0 f5 bf 35 (11100000 11110101 10111111 00110101) (901772768)
4 4 (object header) 3a 00 00 00 (00111010 00000000 00000000 00000000) (58)
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-monitor1锁释放后为无锁001=====================
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-monitor2偏向锁101=====================
java.lang.Object 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) 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-monitor2偏向锁101=====================
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 f9 fb (00000101 00000000 11111001 11111011) (-67567611)
4 4 (object header) f1 01 00 00 (11110001 00000001 00000000 00000000) (497)
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-monitor2锁释放后为偏向锁101=====================
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 f9 fb (00000101 00000000 11111001 11111011) (-67567611)
4 4 (object header) f1 01 00 00 (11110001 00000001 00000000 00000000) (497)
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
=====================pool-1-thread-1-monitor2重量锁10=====================
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 4a 91 c3 ff (01001010 10010001 11000011 11111111) (-3960502)
4 4 (object header) f1 01 00 00 (11110001 00000001 00000000 00000000) (497)
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-monitor2重量级锁10=====================
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 4a 91 c3 ff (01001010 10010001 11000011 11111111) (-3960502)
4 4 (object header) f1 01 00 00 (11110001 00000001 00000000 00000000) (497)
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-monitor2释放锁为无锁001=====================
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
package com.yujie;
import org.openjdk.jol.info.ClassLayout;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
//无锁001
Object monitor1 = new Object();
System.out.println("====================="+Thread.currentThread().getName()+"-monitor1无锁001=====================");
System.out.println(ClassLayout.parseInstance(monitor1).toPrintable());
synchronized (monitor1){
//轻量级锁解释:因为monitor1是4秒之前创建的所以还没有开启偏向锁
System.out.println("====================="+Thread.currentThread().getName()+"-monitor1轻量级锁00=====================");
System.out.println(ClassLayout.parseInstance(monitor1).toPrintable());
}
System.out.println("====================="+Thread.currentThread().getName()+"-monitor1锁释放后为无锁001=====================");
System.out.println(ClassLayout.parseInstance(monitor1).toPrintable());
//jdk8延时4秒后新创建的对象都会开启偏向锁
sleep5();
Object monitor2 = new Object();
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2偏向锁101=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
synchronized (monitor2){
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2偏向锁101=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
}
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2锁释放后为偏向锁101=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
executorService.execute(new Runnable() {
@Override
public void run() {
synchronized (monitor2){
sleep5();
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2重量锁10=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
}
}
});
//锁竞争开始
synchronized (monitor2){
sleep5();
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2重量级锁10=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
}
sleep5();
sleep5();
System.out.println("====================="+Thread.currentThread().getName()+"-monitor2释放锁为无锁001=====================");
System.out.println(ClassLayout.parseInstance(monitor2).toPrintable());
}
public static void sleep5(){
try {
//模拟业务睡眠5秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Note that the monitor1 object is tested after the biased lock is not enabled, and the monitor2 is tested after the biased lock is enabled
View object header dependencies
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
Summarize:
1. After the bias lock is released, it is still a bias lock
2. No lock after the lightweight lock is released
3. No lock after the weight lock is released