看synchronized之前先了解一下对象头里面的内容:
一个小demo,运行一下
public class MyThred {
static TestDemo testDemo;
public static void main(String[] args) throws Exception {
testDemo= new TestDemo();
System.out.println(ClassLayout.parseInstance(testDemo).toPrintable());
}
}
class TestDemo{
boolean a;
}
输出结果:
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) 43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
12 1 boolean TestDemo.a false
13 3 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total
然后第一个字节的后三位就是锁标志位
看该图也知道了为什么gc最大为15,(2^4-1=15)
然后看synchronized各种锁的验证:
/*
synchronzied同步块锁 验证
*/
public class MyLockSYNC {
/*
锁标识位 后三位 第一位为偏向标识位 1为偏向 ,最后两位分别标识 00轻量级 01偏向/无 10重量级 11GC
*/
public static void main(String[] args) throws Exception{
//methodA();
//methodB();
//methodC();
methodD();
}
/*
未加偏向锁,虚拟机在启动的时候对于偏向锁有延迟,延迟是4000ms,所以该段代码没有加上偏向锁
*/
public static void methodA() throws Exception{
ObjectA objectA = new ObjectA();
System.out.println("befor lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000001 无锁
synchronized (objectA){
System.out.println("lock ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00011000 轻量级锁
}
System.out.println("after lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000001 无锁
}
/*
偏向锁,延迟5S后加上了偏向锁
*/
public static void methodB() throws Exception{
sleep(5000);
ObjectA objectA = new ObjectA();
System.out.println("befor lock");
//为什么加锁前也是偏向锁,因为jvm自动加了偏向锁
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
synchronized (objectA){
System.out.println("lock ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
}
System.out.println("after lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101偏向锁
}
/*
轻量级锁
*/
public static void methodC() throws Exception{
sleep(5000);
ObjectA objectA = new ObjectA();
System.out.println("befor lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
Thread thread = new Thread(() -> {
synchronized (objectA) {
}
});
thread.start();
System.out.println("thread ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
synchronized (objectA){
System.out.println("lock ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000000 轻量级锁
}
System.out.println("after lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000001 无锁
}
/*
重量级锁
*/
public static void methodD() throws Exception{
sleep(5000);
ObjectA objectA = new ObjectA();
System.out.println("befor lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
Thread thread = new Thread(() -> {
synchronized (objectA) {
long endTime;
long startTime = System.nanoTime();
System.out.println(LocalDateTime.now());
do {
endTime = System.nanoTime();
} while (startTime + 1 >= endTime);
}
});
thread.start();
System.out.println("thread ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000101 偏向锁
synchronized (objectA){
System.out.println("lock ing");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000010 重量级锁
}
System.out.println("after lock");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000010 重量级锁
System.gc();
System.out.println("after gc");
System.out.println(ClassLayout.parseInstance(objectA).toPrintable()); //00000001 无锁
}
}