锁消除、锁粗化、偏向锁、适应性锁

锁消除

锁消除是JIT编译器对内部锁实现的一种优化。JIT可以借助逃逸分析来判断同步块的锁对象是否只是被一个线程访问,如果是的话,则在编译期间不生成内部锁的申请与释放对应的机器码,即消除了锁的使用。这种技术被称为锁消除。它可以减少锁的开销。
在这里插入图片描述
上面的代码在编译时,经过锁消除后,可以等效为下面的:
在这里插入图片描述

StringBuffer是线程安全的类,其append方法和toString方法都是用内部锁进行修饰的,但是当作为方法的局部变量时,因为只会有当前线程对该变量进行访问,所以JIT会进行锁的消除。
如下面代码,当JIT编译doSomething方法时,会将stringBuffer.append和 stringBuffer.toString方法复制到doSomething方法的方法体中,这种技术被成为内联。下面的代码,会对StringBuffer的append和toString方法进行锁的消除。

  private static void doSomething() {

        StringBuffer stringBuffer = new StringBuffer();

        stringBuffer.append("1");

        String s = stringBuffer.toString();
    }

注意:
并不是所有的方法都会进行锁消除,锁的消除技术依赖于JIT的内联优化,至于哪些方法会被内联,要取决于该方法的热度和该方法字节码的尺寸。

锁消除的好处是我们在需要使用锁的场景时,不用考虑锁的开销,只需要关注我们的业务逻辑即可,JIT会对我们的代码进行锁的消除。
但并不是所有方法都会进行锁消除,这个还是要取决于JIT。锁消除是默认开启的。

锁粗化

锁粗化也是JIT编译器对内部锁的一种优化。
在这里插入图片描述

如上面的代码,这些同步块使用的是同一把锁,则JIT会将这些同步块合并为一个大的同步块,从而减少了锁申请、释放的开销。上面的代码会被JIT粗化成如下代码:
在这里插入图片描述
相邻同步块之间如果存在其他语句,也不一定会阻碍JIT编译器进行锁的粗化,因为JIT编译器可能会在执行锁粗化前进行指定重排序,将这些语句排序到同一临界区内。
锁粗化可能会使一个线程持有一个内部锁的时间变长,从而导致其他线程申请该锁的时间也变长,阻塞了其他线程。因此,锁粗化不会被应用到循环体内的相邻同步块中。锁粗化是默认开启的。

偏向锁

偏向锁是java虚拟机对锁实现的一种优化。当大多数锁没有被争用时,并且在整个生命周期至多只会被一个线程持有,java虚拟机也会对其进行申请锁和释放锁,这就带来了昂贵的开销。因此,jvm会为每个对象维护一个偏好,即一个对象对应的内部锁第一次被一个线程获得时,则该线程就会被记录为该对象的偏好线程,这个线程在后续对该锁的访问都无需申请和释放锁,从而减少了开销。

然而,当该对象被偏好线程以外的线程申请锁时,jvm会回收该对象对原线程的偏好,并重新设置该对象的偏好线程,这个过程的代价也比较昂贵,因此,偏向锁的优化只适用于当前对象没有被大量线程争用的场景。
偏向锁的优化是默认开启的。

适应性锁

适应性锁是JIT编译器对内部锁实现所做的一种优化。
当一个线程获取某个对象的锁时,该锁如果被其他线程占用,则该线程会进行暂停,变为非Runnable状态,由于暂停会导致上下文切换,因此暂停这种方法适用于大多数线程对该锁持有时间比较长的场景,这样才能抵消上下文切换的开销。另外一种方式就是采用忙等,忙等就是当锁被占有时,当前线程不被阻塞,而是执行空的循环,直到获取到锁。
忙等的好处是不会导致上下文切换,但如果等待的时间太长,则会一直执行下去,从而消耗cpu资源。因此忙等适用于绝大多数线程对该锁的持有时间较短的场景。

jvm可以根据不同的场景来选择上面的两种策略。对于线程持有时间较长的锁,jvm会采用暂停的策略,对于线程持有时间较短的锁,jvm会采用忙等的策略。jvm也可能先采用忙等的策略,忙等失败的情况下再采用暂停的策略。jvm的这种优化被成为适应性锁

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值