- Java 对象头
- Monitor(锁)
- 原理之 synchronized(4.11多线程--Monitor1)
- 原理之 synchronized 进阶
- 轻量级锁
- 锁膨胀
- 自旋优化(4.11多线程--Monitor2)
- 偏向锁
偏向锁
- 偏向状态
- 撤销 - 其他线程使用对象
- 撤销 - 调用对象 hashCode
- 撤销 - 调用 wait/notify
- 批量重偏向
- 批量撤销
轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。
Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 时 将线程 ID 设置到对象的 Mark Word 头,之后发现这个线程 ID 是自己的就表示没有竞争,不用重新 CAS,以后只要不发生竞争,这个对象就归该线程所有。
static final Object obj = new Object();
public static void method1(){
synchronized(obj){
//同步块A
method2();
}
}
public static void method2(){
synchronized(obj){
//同步块B
}
}
public static void method3(){
synchronized(obj){
//同步块C
}
}
1. 偏向状态
一个对象创建时:
- 如果开启了偏向锁(默认开启),那么对象创建后,Mark Word 值为 0x05 即最后 3 位为 101(可以偏向,但还未加锁,执行到 同步代码才加),这时他的 thread epoch(批量重偏向/批量撤销时用) age 都为 0,加锁时赋值。
- 偏向锁是默认延迟的,不会再程序启动时立即生效,如果想避免延迟,可以加 VM 参数 -XX:BiasedLockingStartupDelay=0 来禁用延迟
- 如果没有开启偏向锁,那么对象创建后,MarkWord 值为 0x01 即最后三位为 001,这时它的 hashcode 、age 都为 0,第一次用到 hashcode 时才会赋值
1)测试延迟特性
2)测试偏向锁
处于偏向锁的对象解锁后,线程ID 仍存储于对象头中
3)测试禁用
在上面测试代码运行时 添加 VM 参数 -XX:-UseBiasedLocking 禁用偏向锁,使用轻量级锁
4)调用对象的 hashCode() 方法
2. 撤销 - 其他线程使用对象
new Thread(()->{
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
synchronized (d){
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
}
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
synchronized (BiasedDemo2.class){// 避免 两个线程 同时请求 d 资源
BiasedDemo2.class.notify();
}
},"t1").start();
new Thread(()->{
synchronized (BiasedDemo2.class){// 避免 两个线程 同时请求 d 资源
try {
BiasedDemo2.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
synchronized (d){
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
}
CommonUtils.getMarkWord(ClassLayout.parseInstance(d).toPrintable());
},"t2").start();
Thread [t1] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000101
Thread [t1] 00000000 00000000 00000000 00000000 00100001 01000111 11100000 00000101
Thread [t1] 00000000 00000000 00000000 00000000 00100001 01000111 11100000 00000101
Thread [t2] 00000000 00000000 00000000 00000000 00100001 01000111 11100000 00000101
Thread [t2] 00000000 00000000 00000000 00000000 00100001 10010011 11110100 01100000
Thread [t2] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
3. 撤销 - 调用对象hashCode
新对象的 hashCode 默认为 0,当第一次调用了 hashCode() 方法后,要在对象头中存放 hashcode 值 占 31 位,对象头中没有地方再存放 threadid 等内容了,所以禁用调可偏向锁状态。(轻量级锁会将对象的hashcode 放到 栈帧中的锁记录里,重量级锁会将对象的 hashcode 放到 Monitor 里,释放锁后 再进行交换)
Dog1 d = new Dog1();
d.hashCode();// 调用该方法,会禁用偏向锁
String printable = ClassLayout.parseInstance(d).toPrintable();
CommonUtils.getMarkWord(printable);
Thread [main] 00000000 00000000 00000000 00000000 11000101 00111111 01000100 00000001
4. 撤销 - 调用 wait/notify(只有重量级锁有,会将偏向锁/轻量级锁禁用)
5. 批量重偏向
如果对象虽然有多个线程访问,但没有竞争,这时偏向了线程 t1 的对象仍有机会重新偏向 t2 ,重偏向会重置对象的 ThreadID
当撤销偏向锁次数炒作阈值 20 次时,第 20 次,JVM 会觉得自己偏向错了,于是会给这些对象加锁时重新偏向至加锁线程
// 线程安全的 list 集合
Vector<Dog3> list = new Vector<>();
Thread t1 = new Thread(()->{
for (int i = 0; i < 30; i++) {
Dog3 d = new Dog3();
list.add(d);
synchronized (d){// VM 参数 -XX:BiasedLockingStartupDelay=0 ,取消可偏向状态的延迟
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
}
synchronized (list){// 同步 list ,实现线程 t2 等待 线程 t1 执行完后再执行,两个线程错开访问共享资源
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<list.size();i++) {
Dog3 d = list.get(i);
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
synchronized (d){
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
},"t2");
t2.start();
}
输出结果:
1、线程 t1 加锁时,不存在竞争,30 个对象 都是可偏向状态 101 ,线程 ID
Thread [t1] - [0] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [1] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [2] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [3] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [4] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [5] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [6] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [7] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [8] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [9] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [10] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [11] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [12] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [13] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [14] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [15] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [16] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [17] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [18] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [19] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [20] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [21] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [22] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [23] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [24] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [25] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [26] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [27] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [28] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t1] - [29] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
=================================
2、线程 t2 启动后,前 19 个对象,加锁前 还都是可偏向状态 101 + 线程 t1 的ID,加锁后,撤销可偏向状态,改为轻量级锁 00 + lock record 地址;第 20 个对象开始,JVM 觉得自己偏向锁加错了,每个对象撤销偏向锁消耗性能,所以就把第 20 个及之后的对象 批量重偏向到新线程 t2 ,101 + 线程 t2 ID;释放锁以后还是偏向线程 t2 的可偏向状态;
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00100010 01100011 11110110 10110000
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 11011110 01101000 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 11011110 01111001 00000101
6. 批量撤销
当撤销偏向锁次数超过阈值 40 次后,JVM 会觉得自己确实偏向错了,根本不该偏向,于是这个类的所有对象都会变为不可偏向的,新建的对象也是不可偏向的
static Thread t1,t2,t3;
public static void main(String[] args) throws InterruptedException {
// 线程安全的 list 集合
Vector<Dog4> list = new Vector<>();
int loopNumber = 38;
t1 = new Thread(()->{
for (int i = 0; i < loopNumber ; i++) {
Dog4 d = new Dog4();
list.add(d);
synchronized (d){// VM 参数 -XX:BiasedLockingStartupDelay=0 ,取消可偏向状态的延迟
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
}
LockSupport.unpark(t2);
},"t1");
t1.start();
t2 = new Thread(()->{
LockSupport.park();
System.out.println("=================================");
for (int i = 0;i<list.size();i++) {
Dog4 d = list.get(i);
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
synchronized (d){
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
LockSupport.unpark(t3);
},"t2");
t2.start();
t3 = new Thread(()->{
LockSupport.park();
System.out.println("=================================");
for (int i = 0;i<list.size();i++) {
Dog4 d = list.get(i);
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
synchronized (d){
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
CommonUtils.getMarkWord1(ClassLayout.parseInstance(d).toPrintable(),i);
}
},"t3");
t3.start();
t3.join();
CommonUtils.getMarkWord(ClassLayout.parseInstance(new Dog4()).toPrintable());
}
输出结果:
1、线程 t1 执行,对象都是可偏向状态,加锁时,所有对象的 Mark Work 存放线程 t1 的ThreadID
Thread [t1] - [0] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [1] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [2] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [3] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [4] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [5] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [6] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [7] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [8] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [9] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [10] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [11] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [12] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [13] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [14] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [15] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [16] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [17] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [18] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [19] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [20] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [21] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [22] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [23] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [24] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [25] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [26] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [27] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [28] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [29] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [30] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [31] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [32] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [33] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [34] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [35] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [36] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [37] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t1] - [38] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
=================================
2、线程 t2 执行,前 19 个对象,加锁前 是 可偏向状态 101 + 线程 t1 的 ThreadID;加锁后,撤销可偏向状态变为轻量级锁 00 + lock record ID;释放锁后,变成不可偏向状态 001;
3、撤销可偏向达到阈值 20 时,从第 20 个对象开始,不再撤销可偏向状态;而是将对象偏向新的线程 t2 ,加锁中、释放锁后,对象的状态为 可偏向状态 101 + 线程 t2 的ThreadID;
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [0] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [1] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [2] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [3] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [4] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [5] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [6] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [7] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [8] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [9] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [10] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [11] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [12] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [13] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [14] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [15] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [16] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [17] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00100010 00000011 11110010 00000000
Thread [t2] - [18] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [19] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [20] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [21] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [22] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [23] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [24] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [25] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [26] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [27] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [28] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [29] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [30] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [30] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [30] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [31] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [31] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [31] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [32] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [32] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [32] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [33] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [33] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [33] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [34] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [34] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [34] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [35] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [35] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [35] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [36] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [36] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [36] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [37] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [37] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [37] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [38] 00000000 00000000 00000000 00000000 00100001 01111110 01110000 00000101
Thread [t2] - [38] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t2] - [38] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
=================================
4、线程 t3 执行时,前 19 个对象 加锁前 在 线程 t2 执行时,已经是 不可偏向 001 ;加锁中,对象 Mark Word 为 轻量级锁 + lock record ID;释放锁后,又变为 不可偏向 001;
Thread [t3] - [0] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [0] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [0] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [1] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [1] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [1] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [2] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [2] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [2] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [3] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [3] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [3] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [4] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [4] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [4] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [5] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [5] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [5] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [6] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [6] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [6] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [7] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [7] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [7] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [8] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [8] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [8] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [9] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [9] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [9] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [10] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [10] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [10] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [11] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [11] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [11] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [12] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [12] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [12] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [13] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [13] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [13] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [14] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [14] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [14] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [15] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [15] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [15] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [16] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [16] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [16] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [17] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [17] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [17] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [18] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [18] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [18] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
5、从第 20 到 38 个对象,加锁前是可偏向状态 101 + 线程 t2 的ThreadID;加锁时,撤销可偏向,加轻量级锁 00 + lock record ID;释放锁后,变为不可偏向 001;
Thread [t3] - [19] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [19] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [19] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [20] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [20] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [20] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [21] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [21] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [21] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [22] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [22] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [22] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [23] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [23] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [23] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [24] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [24] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [24] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [25] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [25] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [25] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [26] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [26] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [26] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [27] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [27] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [27] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [28] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [28] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [28] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [29] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [29] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [29] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [30] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [30] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [30] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [31] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [31] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [31] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [32] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [32] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [32] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [33] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [33] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [33] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [34] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [34] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [34] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [35] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [35] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [35] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [36] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [36] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [36] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [37] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [37] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [37] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
Thread [t3] - [38] 00000000 00000000 00000000 00000000 00100001 01111110 10100001 00000101
Thread [t3] - [38] 00000000 00000000 00000000 00000000 00100010 00010011 11110010 00110000
Thread [t3] - [38] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
6、线程 t2 撤销 0 - 18 对象可偏向,线程 t3 撤销 19 - 38 可偏向,共 39 次,达到阈值,JVM 会认为 线程对这个类的竞争比较激烈,不适合偏向锁(撤销太多影响性能),所以这个类的所有对象都变成不可偏向状态;
7、如果 loopNumber = 37 ,此处创建的新对象仍然是 可偏向 101;如果 loopNumber > 38 ,第 38 个之后的对象,加锁前,仍然是 可偏向 101 + 线程 t2 ThreadID ;加锁时,撤销可偏向,加轻量级锁 00 + lock record ID;释放锁后,不可偏向 001;
Thread [main] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001
7. 锁消除
@BenchmarkMode(Mode.AverageTime) 统计两个方法的平均运行时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)平均运行时间单位是纳秒
@Warmup(iterations=3) 预热次数,让代码充分优化,得到最真实的结果
@Measurement(iterations=5) 代码要测试 5 论
java 中的 JIT 即时编译器 在编译代码的过程中,加锁对象 o 是局部变量,线程之间不会产生竞争,所以会把 synchronized 优化掉。所以方法 a b 的平均执行时间几乎相同。