美文网首页
JVM锁消除和锁粗化

JVM锁消除和锁粗化

作者: cbhe | 来源:发表于2020-05-26 20:51 被阅读0次

锁消除和锁粗化都是jvm对于锁的优化措施

锁消除

锁消除就是字面意思,虚拟机会根据自己的代码检测结果取消一些加锁逻辑。虚拟机通过检测会发现一些代码中不可能出现数据竞争,但是代码中又有加锁逻辑,为了提高性能,就消除这些锁。如果一段代码中,在堆上的所有数据都不会被其他线程访问到,那就可以把它们当成线程私有数据,自然就不需要同步加锁了。
最典型的例子就是多个String变量连接时的代码:

String s1 = "hello";
String s2 = "world";
String s3 = s1+s2;

经过编译器优化后,这段代码就变成了下面的样子:

StringBuffer sb = new StringBuffer();
sb.append("hello");
sb.append("world");
s3 = sb.toString();

因为我们知道append方法时一个同步方法,它的方法签名是:

public synchronized StringBuffer append(String str);

这时候,编译器就会判断出sb这个对象并不会被这段代码块以外的地方访问到,更不会被其他线程访问到,这时候的加锁就是完全没必要的,编译器就会把这里的加锁代码消除掉,体现到java源码上就是把append方法的synchronized修饰符给去掉了。

锁粗化

原则上,我们在编写代码的时候,总是推荐将同步块的作用范围限制得尽量小---只在共享数据的实际作用域内才进行同步,这样是为了使得需要同步的操作数量尽可能变少,即使存在锁竞争,等待锁的线程也能进可能快地拿到锁。
大多数情况下,上面的原则都是对的,但是如果一系列的连续操作都对同一个对象反复加锁解锁,甚至加锁操作时出现在循环体中,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗。
看以下代码:

public void method(String s1, String s2){
    synchronized(this){
        System.out.println("s1");
    }
    synchronized(this){
        System.out.println("s1");
    }
}

编译成字节码后的样子如下,注意其中写着作者注的地方

         0: aload_0
         1: dup
         2: astore_3
         3: monitorenter 
         4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         7: ldc           #3                  // String s1
         9: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        12: aload_3
        13: monitorexit // 作者注:这行代码会被jvm去掉
        // 作者注:这里省略了不关注的代码
        20: monitorexit // // 作者注:这行代码会被jvm去掉
        21: aload         4
        23: athrow
        24: aload_0
        25: dup
        26: astore_3
        27: monitorenter
        28: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        31: ldc           #3                  // String s1
        33: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        36: aload_3
        37: monitorexit
        38: goto          48
        41: astore        5
        43: aload_3
        44: monitorexit
        45: aload         5
        47: athrow
        48: return

其实也就是想到与将代码优化成了这样子:

public void method(String s1, String s2){
    synchronized(this){
        System.out.println("s1");
    // }
    // synchronized(this){
        System.out.println("s1");
    }
}

相关文章

  • JVM锁消除和锁粗化

    锁消除和锁粗化都是jvm对于锁的优化措施 锁消除 锁消除就是字面意思,虚拟机会根据自己的代码检测结果取消一些加锁逻...

  • 锁优化

    概述 本文主要论述jvm的各种锁优化技术,主要分为适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁。这些技术都是为了在...

  • JAVA常用的锁机制

    Synchronized 实现依赖JVM,随着jdk版本升级从1.5的重量级锁,1.6的适应自旋、锁消除、锁粗化、...

  • JVM中的锁优化

    锁优化 Jvm 在加锁的过程中,会采用自旋、自适应、锁消除、锁粗化等优化手段来提升代码执行效率。 什么是锁升级,降...

  • 关于synchronized的锁升级自旋问题

    1.6之后对synchronized做了优化,包括锁消除、锁粗化、自旋和锁升级的过程:偏向锁、轻量级锁、重量级锁。...

  • Java锁粗化和锁消除

    锁粗化 通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽可能短,但是大某些情况下,一个程序对同...

  • 锁消除 与 锁粗化

    锁消除 如上图示例, object在方法外部, 此为正常的同步方法. 若将Object object =new O...

  • synchronized

    synchronized synchroized 是一个重量级锁,但是现在经过优化后,引入了自旋锁、锁消除、锁粗化...

  • java面试题 --- 并发②

    1. JDK1.6 开始对 synchronized 做了哪些优化?使用了锁升级、锁粗化、锁消除等方式来优化性能。...

  • JDK的锁优化

    JDK1.6重点提升了并发性能,HotSpot开发团队实现了各种锁优化技术,如适应性自旋锁、锁消除、锁粗化、轻量级...

网友评论

      本文标题:JVM锁消除和锁粗化

      本文链接:https://www.haomeiwen.com/subject/ykvyahtx.html