面试系列之synchronize

面试系列之synchronize

两方面

- synchronize之锁升级过程:

  • 偏向锁:偏向锁是利用对象头中的MarkWord存储偏向的线程Id。锁撤销必须到达安全点之后才能进行(锁撤销消耗性能的原因)
  • 偏向锁延迟:jvm在启动时会大量用到synchronize,而且大部分都存在竞争,所以为了效率在启用阶段是禁用偏向锁的。在启动完成4秒以后开启偏向锁(当然也可以通过参数指令关闭偏向锁延迟),当偏向锁延迟关闭或者jvm启动4s以后,创建的对象直接就是匿名偏向状态(锁状态为偏向锁状态,但是为偏向任何线程称为匿名偏向锁状态 — 可偏向但为偏向状态)
  • hashCode对偏向锁的影响:我们都知道偏向锁的偏向线程号是存储在MarkWord中,hashCode也是存在MarkWord中,所以在执行完hashcode以后MarkWord中就已经没有足够的空间存储对应的线程Id了。这种情况下如果锁对象处于匿名偏向状态,就会直接进行锁撤销,变成无锁状态,如果锁对象处于偏向状态,就会直接升级为重量级锁。(此处为什么是重量级锁,为什么不是轻量级锁。就很奇怪?)
  • wait和notify对偏向锁的影响:因为wait是基于monitor实现的所以,在执行wait方法时需要获取monitor对象,也就变成了重量级锁。执行notify之后变成轻量级锁(此处疑惑)
  • 无锁
  • 轻量级锁:当偏向锁产生少量竞争以后会升级为轻量级锁,进行一次cas进行抢占。会在栈上开辟部分内存,存储锁对象,锁对象包含无锁状态的MarkWord(方便锁释放后变为无锁状态),当出现重入场景时会再次放一个锁对象到栈里面但是这个锁对象不包含无锁状态的MarkWord。
  • 重量级锁:当轻量级锁抢占失败,就会进行锁膨胀,锁膨胀就是在获取monitor对象,获取成功以后也不会马上park。park意味着要进行内核态和用户态的切换(非常消耗性能)。在此处会多次进行自旋尝试抢锁。目的就是减少线程的挂起次数。
  • 重量级锁的实现:重量级锁是基于管程的MESA模型。它定义了,在操作一个共享变量时多个线程需要排队,并且可以有多个条件变量,每个条件变量也有自己的排队队列。synchronized优化了这个模型。它的实现是moniter对象,它存在三个队列(_cxq,enterList,waitSet)。当多个线程竞争时,在_cxq进行排队,并且cxq还是一个使用头插法先进后出的队列(此处体现了非公平锁)。默认策略下:执行wait方法后,线程会进入waitSet队列进行排队。当其他线程执行notifyAll时会将waitSet队列的线程放到enterList的头部进唤醒处理。
    MESA模型
    默认情况下重量级锁的过程
    锁升级过程

锁优化

  1. 批量偏向锁重偏向:当一批锁偏向同一个线程,然后另一个线程前来争抢锁,正常来说该锁会升级为轻量级锁,但是在这种撤销到达默认值20的阈值以后,jvm就会优化为后面的锁对象统一重偏向为另一个线程,而不是升级为轻量级锁批量重定向

  2. 批量锁批量锁撤销:当默认时间25s内,偏向撤销达到阈值40的时候,jvm就会认为你这个程序使用偏向锁是有问题的,就会剥夺这个程序使用偏向锁的权利。后面新创建的对象默认都是无锁状态批量撤销

  3. 自适应自选:自适应自旋是在重量级锁加锁过程中,为了减少线程挂起的次数,会在park之前,多次使用自旋来尝试获取锁,但是这里的自旋使用自适应自选,会通过之前的自旋结果动态的改变自旋的次数

  4. 锁消除:jit会进行线程逃逸分析,如果一个变量的使用并没有超出一个线程的工作范围,那么就算你使用了synchronize,也不会存在加锁动作。

  5. 锁粗化:当你使用锁的时候,多个锁连续使用,jit会将这些锁粗化,也会就是扩大锁的作用方位,减少加锁和解锁的次数

  6. 方法逃逸分析/线程逃逸分析:

  • 锁消除
  • 堆上分配转栈上分配
  • 标量替换

CAS比较并交换,juc包中存在大量的Atomicxxxx 类,使用cas+自旋的方式。 在大量并发的情况下会存在大量想成自旋,影响性能,所以DoubleAdder/LongAdder 采用分段锁的方式,大量线程并不会对一个内存偏移量做处理,而是增加数据,让不同的线程操作数据不同的元素去操作,最后进行汇总。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值