栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

锁消除、锁粗化、锁膨胀

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

锁消除、锁粗化、锁膨胀

一、锁消除

锁消除是指虚拟机即时编译器在运行时,对一些代码要求同步,但是对被检测到不可能存在共享数据竞争的锁进行消除。锁消除的主要判定依据来源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须再进行

也许读者会有疑问,变量是否逃逸,对于虚拟机来说是需要使用复杂的过程间分析才能确定的,但是程序员自己应该是很清楚的,怎么会在明知道不存在数据争用的情况下还要求同步呢?这个问题的答案是:有许多同步措施并不是程序员自己加入的,同步的代码在Java程序中出现的频繁程度也许超过了大部分读者的想象。我们来看看如下所示的例子,这段非常简单的代码仅仅是输出三个字符串相加的结果,无论是源代码字面上,还是程序语义上都没有进行同步

public String concatString(String s1, String s2, String s3) {
    return s1 + s2 + s3;
}

我们也知道,由于String是一个不可变的类,对字符串的连接操作总是通过生成新的String对象来进行的,因此Javac编译器会对String连接做自动优化。在JDK 5之前,字符串加法会转化为StringBuffer对象的连续append()操作,在JDK 5及以后的版本中,会转化为StringBuilder对象的连续append()操作。即以上代码可能会变成以下所示的样子

public String concatString(String s1, String s2, String s3) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    sb.append(s3);
    return sb.toString();
}

现在大家还认为这段代码没有涉及同步吗?每个StringBuffer.append()方法中都有一个同步块,锁就是sb对象。虚拟机观察变量sb,经过逃逸分析后会发现它的动态作用域被限制在concatString()方法内部。也就是sb的所有引用都永远不会逃逸到concatString()方法之外,其他线程无法访问到它,所以这里虽然有锁,但是可以被安全地消除掉。在解释执行时这里仍然会加锁,但在经过服务端编译器的即时编译之后,这段代码就会忽略所有的同步措施而直接执行 

二、锁粗化

原则上,我们在编写代码的时候,总是推荐将同步块的作用范围限制得尽量小——只在共享数据的实际作用域中才进行同步,这样是为了使得需要同步的操作数量尽可能变少,即使存在锁竞争,等待锁的线程也能尽可能快地拿到锁

大多数情况下,上面的原则都是正确的,但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作是出现在循环体之中的,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗

代码2所示连续的append()方法就属于这类情况。如果虚拟机探测到有这样一串零碎的操作都对同一个对象加锁,将会把加锁同步的范围扩展(粗化)到整个操作序列的外部,以代码2为例,就是扩展到第一个append()操作之前直至最后一个append()操作之后,这样只需要加锁一次就可以了

三、锁膨胀

锁膨胀也称为锁升级,并不同于锁粗化。锁粗化是指锁同步范围的扩大,而锁膨胀是指锁类型升级为更加重量级的锁

Java中的锁一共有4种状态,级别从低到高依次是:无锁、偏向锁、轻量级锁、重量级锁。这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级,意味着偏向锁升级为轻量级锁后不能降级为偏向锁。这种锁升级却不能降级的策略,目的是提高获得锁和释放锁的效率

锁升级过程可以简单理解为,每个对象起始状态都是最低级,但随着线程竞争的发生,这个对象的锁等级会一步一步提高,最终到达重量级锁。因为JDK6以后默认开启偏向锁,所以可以认为每个对象的初始状态都是偏向锁

三种锁的对比

优点缺点适用场景
偏向锁没有加锁、解锁的额外消耗,几乎没有不影响运行速度如果线程间存在竞争,则会带来额外的锁撤销的消耗只有一个线程访问同步块
轻量级锁竞争的线程不会阻塞,提高响应速度如果线程长时间得不到锁会一直自旋消耗CPU资源同步块执行时间短,追求响应时间
重量级锁线程竞争不会自旋,不额外消耗CPU线程阻塞,响应缓慢同步块执行时间长,追求吞吐量

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/321039.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号