文章目录
相关文章:
锁状态位之无锁
锁状态位之偏向锁
锁状态位之轻量级锁
锁状态位之重量级锁
1. 验证重量级锁
我们创建一个对象,没有上锁(可偏向锁,锁标识为偏向锁,但偏向线程ID为空),然后线程A上锁(真正加偏向锁,给偏向线程ID赋值),线程A尚未结束
,线程B接着上锁,此时产生激烈竞争,此时观察锁标识位,我们期望是重量级锁:
import org.openjdk.jol.info.ClassLayout;
public class Test {
public static void main(String[] args) throws InterruptedException {
//保证jvm真正开启偏向锁 或者通过参数-XX:BiasedLockingStartupDelay=0关闭偏向锁延迟
Thread.sleep(5000);
Object a = new Object();
//此时是可偏向的,显示偏向锁,但是偏向线程ID为空
System.out.println(ClassLayout.parseInstance(a).toPrintable());
Thread thread1 = new Thread(){
@Override
public void run() {
synchronized (a){
System.out.println("thread1 locking");
//第一次加锁显示偏向锁,偏向线程ID为当前线程id
System.out.println(ClassLayout.parseInstance(a).toPrintable());
try {
//让线程晚点儿死亡,造成锁的竞争
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
synchronized (a){
System.out.println("thread2 locking");
//第二次加锁显示已升级为重量级锁
System.out.println(ClassLayout.parseInstance(a).toPrintable());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread1.start();
//故意间隔1s,充分显示锁的升级过程
Thread.sleep(1000);
thread2.start();
}
}
执行结果:
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 ff 27 (11100101 00000001 11111111 00100111) (671023589)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
thread1 locking
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 98 0b 1a (00000101 10011000 00001011 00011010) (436967429)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 ff 27 (11100101 00000001 11111111 00100111) (671023589)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
thread2 locking
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 3a a5 2e 02 (00111010 10100101 00101110 00000010) (36611386)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 ff 27 (11100101 00000001 11111111 00100111) (671023589)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Process finished with exit code 0
分析,供打印3次:
第一条打印显示没有上锁(可偏向锁,锁标识为偏向锁,但偏向线程ID为空)
第二条打印显示线程A上锁(真正加偏向锁,给偏向线程ID赋值)
第三条打印显示线程B上锁后,升级为重量级锁
其实,在轻量级锁升级至重量级锁时,中间还经历了自旋锁,自旋次数达到上限后,才会升级为重量级锁