JAVA synchronized锁升级,可重入,非公平

JAVA synchronized锁升级,可重入,非公平

提示

年轻人不讲理论

锁升级

无锁 → 偏向锁 → 轻量级锁 → 重量级锁

伪代码

//伪代码
class A{
    synchronize  hello(){
           hi();
    }
    synchronize hi(){
           sout("hi")
    }
    main(){
    
       A a = new A();
       new Thread( a.hello(), "1线程").start;
       new Thread( a.hello(), "2线程").start;
       new Thread( a.hello(), "3线程").start;
       new Thread( a.hello(), "4线程").start;

    }
}

锁升级过程

最复杂情况下:

  • 1线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁标志为无锁(lock : 01,biased_lock : 0),线程重入次数recursions=0,将锁标志改为偏向锁(lock : 01,biased_lock : 1),a对象头中设置正在运行的线程id为1线程的id,线程重入次数recursions++

  • 1线程调用hi方法,需要锁住a对象,查看对象头锁标志为偏向锁,拥有锁的线程id和自己线程id一致,不需要抢夺锁,只需要将线程重入次数recursions++(可重入)

  • 1线程调用未结束

  • 2线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁标志为偏向锁,将锁标志改为轻量级锁(lock : 00),2线程做CAS自旋,循环获取锁

  • 3线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁标志为轻量级锁,3线程直接做CAS自旋,循环获取锁

  • 2,3线程循环时间达到阈值,或者多个线程都在此自旋(自旋浪费cpu),将a对象头中的锁标志改为重量级锁(lock : 10)

  • 2,3线程查看a对象头锁标志为重量级锁,直接将线程放入a对象头中的线程等待队列,不再自旋

  • 4线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁标志为重量级锁,直接进入等待队列

  • 1线程调用hi结束,线程重入次数recursions - -

  • 1线程调用hello结束,线程重入次数recursions - -

  • 1线程释放锁并唤醒其它等待线程(非公平锁)

  • 等待线程并不是按排队顺序获取锁,而是一起抢夺锁(非公平锁)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值