在上一次https://www.cnblogs.com/webor2006/p/11446473.html中对锁的升级进行了一个比较详细的理论化的学习,先回忆一下:

编译器对于锁的优化措施:

锁消除技术:

接下来则会通过实例来分析一下JIT编译器优化的一些方式,先来看第一个例子:

很简单的程序,然后反编译看一下它在字节码的表现:

接下来则来修改一下程序:

其实反编译的字节码的锁还是会有的:

但是很明显这段同步的意义就不大了,因为每个线程在访问这个方法时的局部变量肯定都是不一样的,不同的对象锁也不一样,那何来的同步,所以其实JIT在程序运行时是比较智能的,JIT编译器(Just In Time编译器)可以在动态编译同步代码时,使用一种叫做逃逸分析的技术,来通过该项技术判别程序中所使用的锁对象是否只被一个线程所使用,而没有散布到其他线程当中;如果情况就是这样的话,那么JIT编译器在编译这个同步代码时就不会生成synchronized关键字标识的锁的申请和释放机器码,从而消除了锁的使用流程。

锁粗化:

好,接下来看另外一个例子:

根据上面的理论,很显然在运行是JIT是不会给代码上锁的,因为此object声明的是方法的局部变量,木啥意义,那如果将它改为成员变量呢?

可见这个方法块中多次给代码上了锁,下面看一下它在字节码上的表现:

  public void method();
Code:
0: aload_0
1: getfield #3 // Field object:Ljava/lang/Object;
4: dup
5: astore_1
6: monitorenter
7: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
10: ldc #5 // String hello world
12: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
15: aload_1
16: monitorexit
17: goto 25
20: astore_2
21: aload_1
22: monitorexit
23: aload_2
24: athrow
25: aload_0
26: getfield #3 // Field object:Ljava/lang/Object;
29: dup
30: astore_1
31: monitorenter
32: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
35: ldc #7 // String welcome
37: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: aload_1
41: monitorexit
42: goto 50
45: astore_3
46: aload_1
47: monitorexit
48: aload_3
49: athrow
50: aload_0
51: getfield #3 // Field object:Ljava/lang/Object;
54: dup
55: astore_1
56: monitorenter
57: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
60: ldc #8 // String person
62: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
65: aload_1
66: monitorexit
67: goto 77
70: astore 4
72: aload_1
73: monitorexit
74: aload 4
76: athrow
77: return
Exception table:
from to target type
7 17 20 any
20 23 20 any
32 42 45 any
45 48 45 any
57 67 70 any
70 74 70 any

每一个synchronized块都对应一个monitorenter和两个monitorexit,其实JIT编译器在执行动态编译时会对上面代码进行优化:若发现前后相邻的synchronized块使用的是同一个锁对象,那么它就会把这几个synchronized块给合并为一个较大的同步块,这样做的好处在于线程在执行这些代码时,就无需频繁申请与释放锁了,从而达到申请与释放锁一次,就可以执行完全部的同步代码块,从而提升了性能。

Java精通并发-锁粗化与锁消除技术实例演示与分析的更多相关文章

  1. (转载)java高并发:CAS无锁原理及广泛应用

    java高并发:CAS无锁原理及广泛应用   版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...

  2. Java线程安全与锁优化,锁消除,锁粗化,锁升级

    线程安全的定义 来自<Java高并发实战>"当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法的时候进行任何 ...

  3. Java精通并发-锁升级与偏向锁深入解析

    对于synchronized关键字,我们在实际使用时可能经常听说用它是一个非常重的操作,其实这个“重”是要针对JDK的版本来说的,如今JDK已经到了12版本了,其实对这个关键字一直是存在偏见的,它底层 ...

  4. Java精通并发-轻量级锁与重量级锁的变化深入详解

    在上一次https://www.cnblogs.com/webor2006/p/11446129.html的理论的最后谈到了锁的演化,如下: 下面具体来阐述一下: 偏向锁:它是针对一个线程来说, 它的 ...

  5. Java高并发情况下的锁机制优化

    本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 1 public synchronized void syncMethod(){ 2 othercode ...

  6. Java线程并发中常见的锁

    随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...

  7. Java线程并发中常见的锁--自旋锁 偏向锁

    随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...

  8. Java精通并发-wait与sleep方法字节码分析

    在上一次https://www.cnblogs.com/webor2006/p/11372521.html中对于Thread类和Runnable接口有了一个基本的认识,这次咱们继续巩固基础,首先先新建 ...

  9. Java精通并发-透过字节码理解synchronized关键字

    在上一次https://www.cnblogs.com/webor2006/p/11428408.html中对于synchronized关键字的作用做了一个实例详解,下面再来看一下这个程序: 请问下, ...

随机推荐

  1. 多核vs多处理器

    多核vs多处理器 多核CPU性能最好,但成本最高:多CPU成本小,便宜,但性能相对较差 线程数=cpu处理器个数 * 一个cpu内的核数[如果有超线程,再乘以超线程数] 多核 CPU 和多个 CPU ...

  2. 深入理解-CLI与PHP-FPM

    原文地址:https://blog.csdn.net/lzx_victory/article/details/85917161 PHP-FPM模式相对于CLI比较复杂,因为PHP-FPM为常驻进程不断 ...

  3. 【电子电路技术】PoE供电技术的优缺点

    转自http://www.mamicode.com/info-detail-1059108.html 1PoE供电稳定吗? 随着近几年网络监控的迅猛发展,技术门槛也是越来越高,厂商提供的技术支持也越来 ...

  4. zap+日志分级分文件+按时间切割日志整合demo

    实现功能     info debug 级别的日志输出到 /path/log/demo.log     warn error .... 级别的日志输出到 /path/log/demo_error.lo ...

  5. 协议——SPI

    SPI(Serial Peripheral interface)是由摩托罗拉公司定义的一种串行外围设备接口,是一种高速.全双工.同步的通信总线,只需要四根信号线即可,节约引脚,同时有利于PCB的布局. ...

  6. Verilog的各种坑

    Verilog语言和软件语言不一样,有些时候理所当然的编写,也没有报语法错误,可是功能就是不对.唉,把遇到的坑都记在本篇博客吧. 1. initial begin...end里面不能有always,如 ...

  7. Java对象深拷贝浅拷贝总结

    目录 深拷贝 1. 手动new 2. clone方法 3. java自带序列化 4. json序列化 性能测试 深拷贝总结 浅拷贝 1. spring BeanUtils(Apache BeanUti ...

  8. vue3 template refs dom的引用、组件的引用、获取子组件的值

    介绍 通过 ref() 还可以引用页面上的元素或组件. DOM 的引用 <template> <div> <h3 ref="h3Ref">Tem ...

  9. YARN-HA高可用集群搭建

    YARN-HA配置 1. YARN-HA工作机制 1.1 官方文档:http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ ...

  10. 利用ime-mode设置文本框只能输入正整数

    html: <input type="text" id="packageratio"style="ime-mode: disabled;&quo ...