maizhen 2021-09-15 07:18 采纳率: 50%
浏览 94
已结题

为啥我的代码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());

        }
    }

}

展开全部

  • 写回答

1条回答 默认 最新

  • yue_hu 2021-09-15 09:45
    关注

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

    ,看是否可以帮助到你。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    maizhen 2021-09-15 12:50

    谢谢大哥,我后续测试发现加上参数-XX:BiasedLockingStartupDelay=0还是不行,后来把 输出object地址的代码去掉才行,而且对象头打印的没了 object的内存地址了,这可能是 对象刚创建时 对象头没有对象内存地址,锁是偏向锁, 调用 hashcode的时候把 对象头地址偏移到了 内存地址无锁的值?然后只能偏向锁到无锁,不能无锁 到 偏向锁?这只是我猜测,总之,谢谢大佬,我又学到了一些知识。

    回复
    yue_hu 回复 maizhen 2021-09-16 01:24

    偏向锁也不会退化成无锁,偏向锁不会像重量级锁那样锁模块执行完毕就进行解锁,偏向锁一旦偏向某个线程就会一直偏向他,没有锁撤销的情况下即使线程已经不在同步代码块也不会清除偏向。即使发生了锁撤销也是回到匿名偏向状态,而不是无锁状态。这一点可以通过偏向锁加锁,然在执行完同步代码块再看锁对象,他还是偏向锁状态,而不是无锁状态验证。

    回复
    maizhen 回复 yue_hu 2021-09-17 02:17

    那为啥我调用toString之后就从101变到001啦。。

    img

    回复
    展开全部7条评论
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 9月22日
  • 已采纳回答 9月15日
  • 创建了问题 9月15日
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部