Java精通并发-锁粗化与锁消除技术实例演示与分析
在上一次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精通并发-锁粗化与锁消除技术实例演示与分析的更多相关文章
- (转载)java高并发:CAS无锁原理及广泛应用
java高并发:CAS无锁原理及广泛应用 版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...
- Java线程安全与锁优化,锁消除,锁粗化,锁升级
线程安全的定义 来自<Java高并发实战>"当多个线程访问一个对象的时候,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法的时候进行任何 ...
- Java精通并发-锁升级与偏向锁深入解析
对于synchronized关键字,我们在实际使用时可能经常听说用它是一个非常重的操作,其实这个“重”是要针对JDK的版本来说的,如今JDK已经到了12版本了,其实对这个关键字一直是存在偏见的,它底层 ...
- Java精通并发-轻量级锁与重量级锁的变化深入详解
在上一次https://www.cnblogs.com/webor2006/p/11446129.html的理论的最后谈到了锁的演化,如下: 下面具体来阐述一下: 偏向锁:它是针对一个线程来说, 它的 ...
- Java高并发情况下的锁机制优化
本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 1 public synchronized void syncMethod(){ 2 othercode ...
- Java线程并发中常见的锁
随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...
- Java线程并发中常见的锁--自旋锁 偏向锁
随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题.本文着重介绍了在java并发中常见的几种锁机制. 1.偏向锁 偏向锁是JDK1.6提出来的一种锁优化的机制.其核心的思想 ...
- Java精通并发-wait与sleep方法字节码分析
在上一次https://www.cnblogs.com/webor2006/p/11372521.html中对于Thread类和Runnable接口有了一个基本的认识,这次咱们继续巩固基础,首先先新建 ...
- Java精通并发-透过字节码理解synchronized关键字
在上一次https://www.cnblogs.com/webor2006/p/11428408.html中对于synchronized关键字的作用做了一个实例详解,下面再来看一下这个程序: 请问下, ...
随机推荐
- [LeetCode] 628. Maximum Product of Three Numbers 三个数字的最大乘积
Given an integer array, find three numbers whose product is maximum and output the maximum product. ...
- Exsi6.6主机网络不通解决办法
Exsi虚拟机网络偶尔不通,防火墙性能不足 解决办法,断开网络连接再重连
- 【SSH进阶之路】Spring的IOC逐层深入——源码解析之IoC的根本BeanFactory(五)
我们前面的三篇博文,简单易懂的介绍了为什么要使用IOC[实例讲解](二).和Spring的IOC原理[通俗解释](三)以及依赖注入的两种常用实现类型(四),这些都是刚开始学习Spring IoC容器时 ...
- JS 各种引擎介绍
JS 各种引擎介绍 http://www.oschina.net/project/tag/296/javascript-engine 不同浏览器有不同的JS引擎: WebKit , Safari浏览器 ...
- win7/win10 设置始终以管理员身份运行cmd窗口
在桌面上找到cmd快捷方式图标,右键"属性" 4.选择"快捷方式",点击“高级” 5.勾选用管理员身份运行,点击"确定" 6.点击" ...
- Java项目main方法启动的两种方式
1.打包时指定了主类,可以直接用java -jar xxx.jar. <!--main方法打包jar包插件--> <plugin> <artifactId>mave ...
- vscode添加vue文件模板
文件->首选项->用户代码片段->输入vue,打开vue.json 添加模板json "Print to console": { "prefix&quo ...
- Python Tkinter 窗口创建与布局
做界面,首先需要创建一个窗口,Python Tkinter创建窗口很简单:(注意,Tkinter的包名因Python的版本不同存在差异,有两种:Tkinter和tkinter,读者若发现程序不能运行, ...
- nodepad++格式化html代码
如果没有安装插件
- Qt去掉treeview项的焦点虚线
项目做到后期,进行局部美化的时候发现了问题,在treeview框选择状态下会有虚线. 其实,不仅是treeview,tableview,listview,乃至button在有焦点的情况下,都会出现虚线 ...