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关键字的作用做了一个实例详解,下面再来看一下这个程序: 请问下, ...
随机推荐
- 【SSH进阶之路】Spring的AOP逐层深入——AOP的基本原理(六)
经过我们对Spring的IOC不断的深入学习,Spring的面貌逐渐变得清晰,我们对Spring的了解也更加的深入.从这篇博文开始我们学习Spring的第二大核心内容:AOP. 什么是AOP AOP( ...
- 高级UI-自定义控件
自定义控件在Android开发中有着大量的运用,为了做出符合项目的效果很多时候需要自定义控件,这里就使用两个自定义控件,来说明自定义控件的使用流程 仿QQ侧滑 之前使用DrawerLayout和Nav ...
- Java中缓存的介绍
一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...
- java中的Stream流
java中的Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定"流"就一定是"IO流"呢?在Java 8中,得益于Lambda所带 ...
- python time模块(13)
python time模块主要包含各种提供日期.时间功能的相关函数.time模块既提供了把日期.时间格式化为字符串的功能,也提供了从字符串恢复日期.时间的功能. 一.前言 在 time 模块内提供了很 ...
- HDU6608-Fansblog(Miller_Rabbin素数判定,威尔逊定理应用,乘法逆元)
Problem Description Farmer John keeps a website called ‘FansBlog’ .Everyday , there are many people ...
- laydate 只设置年月日,时分,不设置秒
laydate.render({ elem: '#deadline_time' ,type: 'datetime' ,format: 'yyyy-MM-dd HH:mm' }); 设置了format, ...
- 超简单的react和typescript和引入scss项目搭建流程
1.首先我们先创建一个react项目,react官网也有react项目搭建的命令 npx create-react-app my-app cd my-app 2.安装我们项目需要的样式依赖,这个项目我 ...
- 【C++札记】拷贝构造函数,浅拷贝和深拷贝
一:拷贝构造函数 拷贝构造函数是一种特殊的构造函数,遵循如下的规则: 1.函数名和类名一致,没有返回值. 2.必须有一个参数,参数是本类型的一个引用变量. 3.拷贝构造函数可以访问参数对象的任意成员( ...
- Python 爬取陈都灵百度图片
Python 爬取陈都灵百度图片 标签(空格分隔): 随笔 今天意外发现了自己以前写的一篇爬虫脚本,爬取的是我的女神陈都灵,尝试运行了一下发现居然还能用.故把脚本贴出来分享一下. import req ...