java并发编程(八)synchronized原理之偏向锁
偏向锁的引入,对轻量级锁的CAS操作进行了优化。轻量级锁需要每次都是用CAS来尝试获取锁,占用CPU时间。
jdk1.6中引入偏向锁后,只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。
一、偏向锁的状态
|----------------------------------------------------------------------------------------------|
| Mark Word(64bits) | State |
|----------------------------------------------------------------------------------------------|
| unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:0| lock:01 | Nomal |
|----------------------------------------------------------------------------------------------|
| thread:54| epoch:2 |unused:1|age:4|biase_lock:1| lock:01 | Biased |
|----------------------------------------------------------------------------------------------|
| ptr_to_lock_record:62 | lock:00 | Lightweight Locked |
|----------------------------------------------------------------------------------------------|
| ptr_to_heavyweight_monitor:62 | lock:10 | Heavyweight Locked |
|----------------------------------------------------------------------------------------------|
| | lock:11 | Marked for GC |
|----------------------------------------------------------------------------------------------|
如上表所示,偏向锁的状态biase_lock是1,lock是01。
下面我们借用jol工具看下状态:
<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
1.1 默认情况下的偏向锁
引入依赖后,有如下代码:
public static void main(String[] args) {
Object lock = new Object();
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
结果:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x000000001be01c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
我们只关注上述结果的mark word 部分,后面的括号当中的内容是non-biasable,就是没开启偏向锁。并且value的值是001结尾,对照上面的Mark Word 状态表的后三位,刚好是无锁状态,0,01。
此处有一个问题,偏向锁是延时的,在刚启动的时候并没有开启,我们可以使用以下参数设置立即生效:
-XX:BiasedLockingStartupDelay=0
设置完参数后再次启动的结果如下,发现16进制的value是5,转为2进制就是101,是上表中偏向锁状态的后三位,并且括号内的内容变成了biasable,具有了偏向锁的能力:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 8 (object header: class) 0x000000001c0a1c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
- 总结:
- 偏向锁是默认开启的,但是是延时的,需要通过参数-XX:BiasedLockingStartupDelay=0禁用延时。
- 对象在创建后,如果开启了偏向锁,thread、epoch、age 都为 0。
- 对象在创建后,如果没有开启偏向锁,hashcode、age 都为 0。
- 禁用偏向锁,使用-XX:-UseBiasedLocking参数。
1.2 线程持有偏向锁
1.2.1 单线程持有
当有线程持有上述偏向锁,那么对象头的Mark Word 会有什么变化呢? 代码如下:
public static void main(String[] args) {
Object lock = new Object();
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
synchronized (lock) {
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
在锁被持有前,持有中,持有后的状态分别如下:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 8 (object header: class) 0x000000001c081c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000000320a005 (biased: 0x000000000000c828; epoch: 0; age: 0)
8 8 (object header: class) 0x000000001c081c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000000320a005 (biased: 0x000000000000c828; epoch: 0; age: 0)
8 8 (object header: class) 0x000000001c081c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
如上所示,当锁被线程持有后,mark word的内容发生了变化。其中value是8字节的全部内容,末尾是005,转化成2进制就是101,确实是使用的偏向锁。在括号内的biased表示偏向锁在哪个线程上,后面的16进制数,就是线程的id。
在锁被释放后,当前对象仍然是持有该偏向锁的。
1.2.2 两个线程竞争
有如下代码,使用main方法的主线程和一个Thread模仿一个锁竞争的情况,看看对象头是如何变化的。
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
// 打印初始状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
synchronized (lock) {
// 打印偏向锁状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
TimeUnit.SECONDS.sleep(2);
}
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synchronized (lock){
// 打印轻量级锁
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
}).start();
TimeUnit.SECONDS.sleep(1);
// 打印无锁
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
结果如下所示:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 8 (object header: class) 0x000000001bbd1c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000002e1a005 (biased: 0x000000000000b868; epoch: 0; age: 0)
8 8 (object header: class) 0x000000001bbd1c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000020b5efe0 (thin lock: 0x0000000020b5efe0)
8 8 (object header: class) 0x000000001bbd1c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x000000001bbd1c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
过程分析:
- 新创建对象,开启偏向锁
- 当主线程获取锁后,独自持有偏向锁,阻塞2s
- 一秒后,另一个线程来竞争此锁,此时因为主线程在阻塞,所以此线程升级成了轻量级锁,如上结果thin lock表示轻量级锁,后面的16进制数表示持有锁的线程id。
- 当主线程再次休息一秒,同步代码块执行完毕,此时释放锁,所以最终变成了无锁状态non-biasable。
1.2.3 多个线程竞争
使用5个线程竞争:
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
// 打印初始状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
synchronized (lock) {
// 打印偏向锁状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
TimeUnit.SECONDS.sleep(2);
}
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
synchronized (lock) {
// 打印轻量级锁
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
}).start();
TimeUnit.SECONDS.sleep(1);
// 5个线程竞争
for (int i = 0; i < 5; i++) {
new Thread(() -> {
synchronized (lock) {
// 打印轻量级锁
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
}).start();
}
TimeUnit.SECONDS.sleep(1);
// 打印无锁
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
结果如下所示:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000002ada005 (biased: 0x000000000000ab68; epoch: 0; age: 0)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x00000000208df7f0 (thin lock: 0x00000000208df7f0)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000001c33a60a (fat lock: 0x000000001c33a60a)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000001c33a60a (fat lock: 0x000000001c33a60a)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000001c33a60a (fat lock: 0x000000001c33a60a)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000001c33a60a (fat lock: 0x000000001c33a60a)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000001c33a60a (fat lock: 0x000000001c33a60a)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x000000001b941c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
前面的过程,与上一小节的测试结果没有不同,不同处在于后面的循环创建的5个线程,此时打印的对象头内容是fat lock,表示重量级锁,其后面跟着的16进制数表示Monitor的地址,多个线程竞争时,未获取到锁的线程将会添加到Monitor的EntryList当中,等待唤醒。
二、锁撤销
2.1 hashcode
在创建对象的时候,hashcode是0,只有当调用该对象后,hashcode才被赋值,如下代码所示:
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
// 打印初始状态
System.out.println(lock);
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
结果如下:
java.lang.Object@16f65612
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x00000016f6561201 (hash: 0x16f65612; age: 0)
8 8 (object header: class) 0x000000001c051c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
- 轻量级锁会在锁记录中记录 hashCode
- 重量级锁会在 Monitor 中记录 hashCode
调用对象的hashcode()方法,会使对象的偏向锁被撤销:
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
// 打印初始状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
synchronized (lock) {
// 打印偏向锁状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
//调用hashcode
lock.hashCode();
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
//再次获取锁
synchronized (lock) {
// 打印偏向锁状态
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
}
结果:
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 8 (object header: class) 0x000000001be21c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000000000305a005 (biased: 0x000000000000c168; epoch: 0; age: 0)
8 8 (object header: class) 0x000000001be21c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000002ed94a8b01 (hash: 0x2ed94a8b; age: 0)
8 8 (object header: class) 0x000000001be21c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000002faf730 (thin lock: 0x0000000002faf730)
8 8 (object header: class) 0x000000001be21c00
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
如上所示:发现调用hashcode后,对象头打印出了hash值,并且将value的值转换成二进制后得到后三位的结果是001,001表示无锁的正常状态。
当再次尝试获取锁的时候,发现获取到的只能是轻量级锁(thin lock)了。
2.2 偏向锁锁撤销 - 升级轻量级锁或重量级锁
这里就是前面偏向锁状态当中,当有多个线程竞争锁的时候,无论是升级成轻量级锁,还是重量级锁,在最终将锁释放后,都会变成无锁状态, 即偏向锁的状态被撤销了。
2.3 重偏向优化
如果对象虽然被多个线程访问,但没有竞争,这时偏向了线程 T1 的对象仍有机会重新偏向 T2,重偏向会重置对象的 Thread ID。
当撤销偏向锁阈值超过 14 次后(这个次数在我的电脑时14,有些人似乎20,暂时不知道怎么设定的),jvm 会这样觉得,我是不是偏向错了呢,于是会在给这些对象加锁时重新偏向至加锁线程。
如下所示,有两个线程,t1组装一个大小为30的集合,结合内创建30个对象。t2在t1处理数据时,通过wait等待,当t1通过notify唤醒t2时,t2开始占有锁(30个对象,每一个都有自己的锁):
public static void main(String[] args) {
test3();
}
public static String print(String s) {
String[] split = s.split("\r\n");
return split[2].substring(41);
}
private static void test3() {
Vector<Object> list = new Vector<>();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 30; i++) {
Object d = new Object();
list.add(d);
synchronized (d) {
System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
}
synchronized (list) {
list.notify();
}
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
synchronized (list) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("===============> ");
for (int i = 0; i < 30; i++) {
Object d = list.get(i);
System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
synchronized (d) {
System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
}, "t2");
t2.start();
}
结果:
0 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
1 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
2 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
3 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
4 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
5 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
6 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
7 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
8 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
9 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
10 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
11 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
12 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
13 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
14 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
15 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
16 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
17 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
18 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
19 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
20 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
21 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
22 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
23 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
24 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
25 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
26 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
27 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
28 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
29 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
===============>
0 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
0 0x00000000210df370 (thin lock: 0x00000000210df370)
0 0x0000000000000001 (non-biasable; age: 0)
1 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
1 0x00000000210df370 (thin lock: 0x00000000210df370)
1 0x0000000000000001 (non-biasable; age: 0)
2 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
2 0x00000000210df370 (thin lock: 0x00000000210df370)
2 0x0000000000000001 (non-biasable; age: 0)
3 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
3 0x00000000210df370 (thin lock: 0x00000000210df370)
3 0x0000000000000001 (non-biasable; age: 0)
4 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
4 0x00000000210df370 (thin lock: 0x00000000210df370)
4 0x0000000000000001 (non-biasable; age: 0)
5 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
5 0x00000000210df370 (thin lock: 0x00000000210df370)
5 0x0000000000000001 (non-biasable; age: 0)
6 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
6 0x00000000210df370 (thin lock: 0x00000000210df370)
6 0x0000000000000001 (non-biasable; age: 0)
7 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
7 0x00000000210df370 (thin lock: 0x00000000210df370)
7 0x0000000000000001 (non-biasable; age: 0)
8 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
8 0x00000000210df370 (thin lock: 0x00000000210df370)
8 0x0000000000000001 (non-biasable; age: 0)
9 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
9 0x00000000210df370 (thin lock: 0x00000000210df370)
9 0x0000000000000001 (non-biasable; age: 0)
10 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
10 0x00000000210df370 (thin lock: 0x00000000210df370)
10 0x0000000000000001 (non-biasable; age: 0)
11 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
11 0x00000000210df370 (thin lock: 0x00000000210df370)
11 0x0000000000000001 (non-biasable; age: 0)
12 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
12 0x00000000210df370 (thin lock: 0x00000000210df370)
12 0x0000000000000001 (non-biasable; age: 0)
13 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
13 0x00000000210df370 (thin lock: 0x00000000210df370)
13 0x0000000000000001 (non-biasable; age: 0)
14 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
14 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
14 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
15 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
15 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
15 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
16 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
16 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
16 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
17 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
17 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
17 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
18 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
18 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
18 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
19 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
19 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
19 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
20 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
20 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
20 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
21 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
21 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
21 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
22 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
22 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
22 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
23 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
23 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
23 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
24 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
24 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
24 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
25 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
25 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
25 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
26 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
26 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
26 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
27 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
27 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
27 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
28 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
28 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
28 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
29 0x0000000020066805 (biased: 0x000000000008019a; epoch: 0; age: 0)
29 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
29 0x0000000020067905 (biased: 0x000000000008019e; epoch: 0; age: 0)
- ===============>之前的30个对象,都是偏向于0x000000000008019e这个线程(t1)。
- ===============>之后开始进行了锁升级,升级成了轻量级锁(thin lock),释放后变成无锁状态(non-biasable)。
- 在经历14次锁升级,锁撤销后,发现第15次不在进行此类操作,而是直接修改偏向线程的id了。
因为锁升级和锁撤销会带来一定的性能损耗,所以jvm在这方面做了重偏向的优化。
2.4 批量锁撤销
当撤销偏向锁阈值超过 14 次后,jvm 会这样觉得,自己确实偏向错了,根本就不该偏向。于是整个类的所有对象都会变为不可偏向的,新建的对象也是不可偏向的。
使用三个线程,初始化一个50个对象的集合,t1处理数据,唤醒t2;t2处理完数据唤醒t3;代码如下:
static Thread t1, t2, t3;
public static void main(String[] args) throws InterruptedException {
test3();
}
public static String print(String s) {
String[] split = s.split("\r\n");
return split[2].substring(41);
}
private static void test3() throws InterruptedException {
Vector<Object> list = new Vector<>();
t1 = new Thread(() -> {
for (int i = 0; i < 50; i++) {
Object d = new Object();
list.add(d);
synchronized (d) {
System.out.println(i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
}
LockSupport.unpark(t2);
}, "t1");
t1.start();
t2 = new Thread(() -> {
LockSupport.park();
System.out.println("=========第二阶段======> ");
for (int i = 0; i < 50; i++) {
Object d = list.get(i);
System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
synchronized (d) {
System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
System.out.println("t2: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
LockSupport.unpark(t3);
}, "t2");
t2.start();
t3 = new Thread(() -> {
LockSupport.park();
System.out.println("=========第三阶段======>");
for (int i = 0; i < 50; i++) {
Object d = list.get(i);
System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
synchronized (d) {
System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
System.out.println("t3: " + i + "\t" + print(ClassLayout.parseInstance(d).toPrintable()));
}
}, "t3");
t3.start();
t3.join();
// 输出一个新的对象的对象头,发现是不可偏向锁
System.out.println(print(ClassLayout.parseInstance(new Object()).toPrintable()));
}
结果:
0 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
1 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
2 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
3 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
4 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
5 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
6 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
7 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
8 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
9 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
10 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
11 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
12 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
13 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
14 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
15 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
16 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
17 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
18 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
19 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
20 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
21 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
22 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
23 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
24 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
25 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
26 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
27 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
28 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
29 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
30 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
31 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
32 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
33 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
34 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
35 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
36 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
37 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
38 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
39 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
40 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
41 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
42 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
43 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
44 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
45 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
46 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
47 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
48 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
49 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
=========第二阶段======>
t2: 0 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 0 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 0 0x0000000000000001 (non-biasable; age: 0)
t2: 1 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 1 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 1 0x0000000000000001 (non-biasable; age: 0)
t2: 2 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 2 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 2 0x0000000000000001 (non-biasable; age: 0)
t2: 3 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 3 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 3 0x0000000000000001 (non-biasable; age: 0)
t2: 4 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 4 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 4 0x0000000000000001 (non-biasable; age: 0)
t2: 5 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 5 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 5 0x0000000000000001 (non-biasable; age: 0)
t2: 6 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 6 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 6 0x0000000000000001 (non-biasable; age: 0)
t2: 7 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 7 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 7 0x0000000000000001 (non-biasable; age: 0)
t2: 8 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 8 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 8 0x0000000000000001 (non-biasable; age: 0)
t2: 9 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 9 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 9 0x0000000000000001 (non-biasable; age: 0)
t2: 10 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 10 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 10 0x0000000000000001 (non-biasable; age: 0)
t2: 11 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 11 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 11 0x0000000000000001 (non-biasable; age: 0)
t2: 12 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 12 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 12 0x0000000000000001 (non-biasable; age: 0)
t2: 13 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 13 0x000000002130f160 (thin lock: 0x000000002130f160)
t2: 13 0x0000000000000001 (non-biasable; age: 0)
t2: 14 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 14 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 14 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 15 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 15 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 15 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 16 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 16 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 16 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 17 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 17 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 17 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 18 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 18 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 18 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 19 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 19 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 19 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 20 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 20 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 20 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 21 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 21 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 21 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 22 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 22 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 22 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 23 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 23 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 23 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 24 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 24 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 24 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 25 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 25 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 25 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 26 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 26 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 26 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 27 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 27 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 27 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 28 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 28 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 28 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 29 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 29 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 29 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 30 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 30 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 30 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 31 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 31 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 31 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 32 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 32 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 32 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 33 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 33 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 33 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 34 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 34 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 34 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 35 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 35 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 35 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 36 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 36 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 36 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 37 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 37 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 37 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 38 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 38 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 38 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 39 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 39 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 39 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 40 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 40 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 40 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 41 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 41 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 41 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 42 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 42 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 42 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 43 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 43 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 43 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 44 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 44 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 44 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 45 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 45 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 45 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 46 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 46 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 46 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 47 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 47 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 47 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 48 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 48 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 48 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 49 0x00000000202aa005 (biased: 0x0000000000080aa8; epoch: 0; age: 0)
t2: 49 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t2: 49 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
=========第三阶段======>
t3: 0 0x0000000000000001 (non-biasable; age: 0)
t3: 0 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 0 0x0000000000000001 (non-biasable; age: 0)
t3: 1 0x0000000000000001 (non-biasable; age: 0)
t3: 1 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 1 0x0000000000000001 (non-biasable; age: 0)
t3: 2 0x0000000000000001 (non-biasable; age: 0)
t3: 2 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 2 0x0000000000000001 (non-biasable; age: 0)
t3: 3 0x0000000000000001 (non-biasable; age: 0)
t3: 3 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 3 0x0000000000000001 (non-biasable; age: 0)
t3: 4 0x0000000000000001 (non-biasable; age: 0)
t3: 4 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 4 0x0000000000000001 (non-biasable; age: 0)
t3: 5 0x0000000000000001 (non-biasable; age: 0)
t3: 5 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 5 0x0000000000000001 (non-biasable; age: 0)
t3: 6 0x0000000000000001 (non-biasable; age: 0)
t3: 6 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 6 0x0000000000000001 (non-biasable; age: 0)
t3: 7 0x0000000000000001 (non-biasable; age: 0)
t3: 7 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 7 0x0000000000000001 (non-biasable; age: 0)
t3: 8 0x0000000000000001 (non-biasable; age: 0)
t3: 8 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 8 0x0000000000000001 (non-biasable; age: 0)
t3: 9 0x0000000000000001 (non-biasable; age: 0)
t3: 9 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 9 0x0000000000000001 (non-biasable; age: 0)
t3: 10 0x0000000000000001 (non-biasable; age: 0)
t3: 10 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 10 0x0000000000000001 (non-biasable; age: 0)
t3: 11 0x0000000000000001 (non-biasable; age: 0)
t3: 11 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 11 0x0000000000000001 (non-biasable; age: 0)
t3: 12 0x0000000000000001 (non-biasable; age: 0)
t3: 12 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 12 0x0000000000000001 (non-biasable; age: 0)
t3: 13 0x0000000000000001 (non-biasable; age: 0)
t3: 13 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 13 0x0000000000000001 (non-biasable; age: 0)
t3: 14 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 14 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 14 0x0000000000000001 (non-biasable; age: 0)
t3: 15 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 15 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 15 0x0000000000000001 (non-biasable; age: 0)
t3: 16 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 16 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 16 0x0000000000000001 (non-biasable; age: 0)
t3: 17 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 17 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 17 0x0000000000000001 (non-biasable; age: 0)
t3: 18 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 18 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 18 0x0000000000000001 (non-biasable; age: 0)
t3: 19 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 19 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 19 0x0000000000000001 (non-biasable; age: 0)
t3: 20 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 20 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 20 0x0000000000000001 (non-biasable; age: 0)
t3: 21 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 21 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 21 0x0000000000000001 (non-biasable; age: 0)
t3: 22 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 22 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 22 0x0000000000000001 (non-biasable; age: 0)
t3: 23 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 23 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 23 0x0000000000000001 (non-biasable; age: 0)
t3: 24 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 24 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 24 0x0000000000000001 (non-biasable; age: 0)
t3: 25 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 25 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 25 0x0000000000000001 (non-biasable; age: 0)
t3: 26 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 26 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 26 0x0000000000000001 (non-biasable; age: 0)
t3: 27 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 27 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 27 0x0000000000000001 (non-biasable; age: 0)
t3: 28 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 28 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 28 0x0000000000000001 (non-biasable; age: 0)
t3: 29 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 29 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 29 0x0000000000000001 (non-biasable; age: 0)
t3: 30 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 30 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 30 0x0000000000000001 (non-biasable; age: 0)
t3: 31 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 31 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 31 0x0000000000000001 (non-biasable; age: 0)
t3: 32 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 32 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 32 0x0000000000000001 (non-biasable; age: 0)
t3: 33 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 33 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 33 0x0000000000000001 (non-biasable; age: 0)
t3: 34 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 34 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 34 0x0000000000000001 (non-biasable; age: 0)
t3: 35 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 35 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 35 0x0000000000000001 (non-biasable; age: 0)
t3: 36 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 36 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 36 0x0000000000000001 (non-biasable; age: 0)
t3: 37 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 37 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 37 0x0000000000000001 (non-biasable; age: 0)
t3: 38 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 38 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 38 0x0000000000000001 (non-biasable; age: 0)
t3: 39 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 39 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 39 0x0000000000000001 (non-biasable; age: 0)
t3: 40 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 40 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 40 0x0000000000000001 (non-biasable; age: 0)
t3: 41 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 41 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 41 0x0000000000000001 (non-biasable; age: 0)
t3: 42 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 42 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 42 0x0000000000000001 (non-biasable; age: 0)
t3: 43 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 43 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 43 0x0000000000000001 (non-biasable; age: 0)
t3: 44 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 44 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 44 0x0000000000000001 (non-biasable; age: 0)
t3: 45 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 45 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 45 0x0000000000000001 (non-biasable; age: 0)
t3: 46 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 46 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 46 0x0000000000000001 (non-biasable; age: 0)
t3: 47 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 47 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 47 0x0000000000000001 (non-biasable; age: 0)
t3: 48 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 48 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 48 0x0000000000000001 (non-biasable; age: 0)
t3: 49 0x00000000202aa905 (biased: 0x0000000000080aaa; epoch: 0; age: 0)
t3: 49 0x000000002140f690 (thin lock: 0x000000002140f690)
t3: 49 0x0000000000000001 (non-biasable; age: 0)
0x0000000000000001 (non-biasable; age: 0)
- 第二阶段其实就是前一章节讲的重偏向优化
- 第三阶段开始,线程t3加入进来,前14个对象在第二阶段已经被撤销了偏向锁,所以这14个对象要不停的经历轻量级锁到锁撤销的状态。
- 当第三阶段达到第15次时,这之后的对象都是偏向于线程t2的,需要经历锁撤销,轻量级锁的过程,到结束并没有进行一个所偏向的优化了。
- 注意最后一行,当再次打印一个新创建的对象头时,发现是不可使用偏向锁的(关于这个阈值,有人说是40,我没有测试过)。