Synchronized简述

本文详细解释了Synchrozied锁在Java中的工作原理,包括悲观锁的使用、不同类型的锁(对象锁、方法锁和类锁)、以及锁升级的过程,特别关注了偏向锁、轻量级锁和重量级锁的转换及其目的。
摘要由CSDN通过智能技术生成

1.了解Synchrozied

        Synchrozied是一种悲观锁,通过Synchroized实现同步机制,在操作数据时,判断该对象是否被锁定,如果被锁定则进入阻塞状态直到被占用的线程释放,如果没有被锁或者当前线程已经存在操作对象的锁则进行上锁操作,操作完成之后在进行释放锁;

        当一个类对象被锁时,被Synchrozied修饰的方法将产生阻塞,非Synchroized修饰的方法不会产生阻塞。Synchroized通过可重入性解决自身锁死的情况;因为他是通过判断对象没有锁或者当前对象的锁来进行加锁,如果没有重入性,一类中两个同步方法互相调用就会造成死锁。

        Synchroized也是一种非公平锁,因为他不会按照申请的时间来分配锁,而是通过竞争的形式来获取锁,这样提高了执行的性能;

  • 方法锁:synchronized修饰方法时,每个实例对象对应一把锁。
  • 对象锁:synchronized修饰方法或代码块,每个实例对象对应一把锁。
  • 类锁:synchronized修饰静态方法或者静态代码块,所有的实例对象共用同一把锁,我们称之为类锁。

2.Synchronized的锁升级过程

        Synchroized锁升级过程:由低到高分别为->偏向锁,轻量级锁,重量级锁;

        升级锁的必要性:在一个线程多次获得同一个锁的情况下,如果每次都要竞争锁会增大很多没有必要的代价,为了降低CPU的开销,提供了执行效率。升级锁的实现,依赖于对象头中的Mark Word,里面会记录当前第一个获取锁的线程ID,以及锁的状态;

        偏向锁:当一个线程A抢到锁之后,将线程A的ID记录在对象头中,并且锁升级为偏向锁;后续线程A再次获取该对象的锁时,发现对象处于偏向锁状态,对象头中的线程ID与线程A一致,此时会直接获取到偏向锁;

        轻量级锁:当另外一个线程B获取锁时,发现锁一级处于偏向锁状态,此时线程B会用过CAS的方式尝试性争抢锁【修改对象头中的线程ID】(判断线程A是否存活,存活就不能进行修改),如果偏向锁抢锁失败,择偏向锁就升级为轻量级锁,如果抢锁成功则执行代码;

        重量级锁:轻量级锁时通过自旋的方式争抢锁,并且适用于线程持有锁的时间不长的情况下(因为阻塞线程需要进行CPU状态,代价太大,所以自旋),当线程的自旋次数超过阈值(默认情况下是10)的时候为了防止cpu空转,会将自旋锁升级为重量级锁,并且将没有获取锁的线程进行阻塞;

        轻量级锁获取锁修改线程ID的方式:偏向锁升级为轻量级锁之后,线程B将锁对象的markword拷贝到线程本身的markword空间中,然后通过CAS的方式去设置锁对象中的线程ID值; 

        

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值