为啥我的代码synchronized锁直接从无锁跳到了轻量级锁

img


从图片中 对象头从 001到000再到001,从无锁跳到了轻量级锁,只有一个线程访问锁的话不是先变成偏向锁的吗?

public class SynchronizedLockInfoTest {

    private static Object object = new Object();




    public static void main(String[] args) {


        System.out.println(object.toString());

        SynchronizedLockInfoTest synchronizedLockInfoTest = new SynchronizedLockInfoTest();

        Thread1 thread1 = synchronizedLockInfoTest.new Thread1();
        thread1.start();


    }


    public class Thread1 extends  Thread{
        @Override
        public void run() {

            Thread thread = Thread.currentThread();
            System.out.println(1);
            System.out.println(thread.getName() + ClassLayout.parseInstance(object).toPrintable());
            synchronized (object){
                System.out.println(2);
                System.out.println(thread.getName() + ClassLayout.parseInstance(object).toPrintable());
            }
            System.out.println(3);
            System.out.println(thread.getName() + ClassLayout.parseInstance(object).toPrintable());

        }
    }

}

因为JVM有一个参数BiasedLockingStartupDelay,意思是偏向锁延迟,默认为4,意思是JVM启动的最初4S禁用偏向锁,这是因为JVM刚启动时竞争比较激烈,并不适合偏向锁,所以跳过这一阶段。这点从对象初始状态是001无锁状态就可以体现出来了,虽然现在网上很多文章都写着无锁状态先膨胀为偏向锁再膨胀为轻量级锁,然而事实是一旦对象创建时是无锁状态,就意味着他是一个禁用偏向锁的对象,一旦加锁会直接进入轻量级锁,如果对象创建时允许偏向锁,那被创建出来时就是101,这时间其实没有偏向任何线程,处于匿名偏向状态,这个你可以修改偏向锁延迟这个参数,或者先休眠4S再加锁你就发现还没加锁对象就是101了,得到验证。
后续测试时如果碰到其他问题可以看一下

,看是否可以帮助到你。