在项目中发现偏向锁并不是立即生效的,而是有着一个默认延迟,下面深入探究一下,为什么偏向锁有着四秒延迟,以及怎么调优

问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @author Lvzixin
* @date 2021/8/26 17:00
*/
public class JOL {
public static void main(String[] args) {
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());

synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}
}

打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 28 f2 5a 03 (00101000 11110010 01011010 00000011) (56291880)
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

然后我们发现,我们明明添加了synchronized,为什么第二次的打印信息为00

image-20210826172322380

不应该是01吗,开始jvm是使用的偏向锁,偏向锁是101啊

探究

原因:

创建一个对象后,jvm偏向锁的启动是有4秒延时的(默认),这个时候为匿名偏向,因为在开始创建的过程中肯定有大量的线程参与竞争(内存分配的竞争等等),这个时候如果立即打开偏向锁的话,肯定是有性能浪费的(锁竞争过程、锁撤掉),所以打开偏向锁的效率不是一定会提升效率。

这个时候我们,在代码最前面添加睡眠5秒钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @author Lvzixin
* @date 2021/8/26 17:00
*/
public class JOL {
public static void main(String[] args) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());

synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}
}

打印:

image-20210826172904965

这个时候状态为101,才升级为偏向锁

调整默认参数

1
2
#jvm中设置立即打开偏向锁
-XX:BiasedLockingStartupDelay=0
image-20210826173209886

然后注释掉睡眠5秒钟

打印:

image-20210826173301227