多线程(7)— JDK对锁优化的努力
JDK内部的“锁”优化策略
1. 锁偏向
锁偏向是针对加锁操作的优化手段,核心思想是:如果一个线程获得了锁,那么锁就进入偏向模式,当这个线程再次请求锁时,无须再做任何同步操作,这样就节省了大量有关锁申请的操作,从而提高了程序的性能。对几乎没有锁竞争的场合,偏向锁有很好的优化效果,对于锁竞争激烈的场合,效果不佳,因为每次都是不同的线程在申请锁,偏向模式就会失效,还不如不启用偏向锁。使用Java虚拟机参数 -XX:+UseBiasedLocking 可以开启偏向锁。
2. 轻量级锁
如果偏向锁失败,虚拟机不会立即挂起线程,会使用一种轻量级锁的优化手段。就是简单地将对象头部作为指针指向持有锁的线程堆栈内部,来判断一个线程是否持有对象锁。如果线程获得轻量级锁成功,可以顺利进入临界区。如果轻量级加锁失败,其他线程已经抢到了锁,当前线程的锁请求会膨胀为重量级锁。
3. 自旋锁
锁膨胀以后,为了避免线程真实地在操作系统层面挂起,虚拟机还会做最后努力--自旋锁。当前线程暂时无法获得锁,而且什么时候可以获得锁是未知数,也许在几个CPU时钟周期内就可以得到锁。系统会假设不久将来线程可以得到这把锁,因此,虚拟机会让当前线程做几个空循环,在经过若干次循环以后,如果可以得到锁,那么就顺利进入临界区。如果还不能得到锁,才会真的将线程在操作系统层面挂起。
4. 锁消除
是一种更彻底的锁优化,Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过锁消除,可以节省毫无意义的请求锁时间。例如在一个不可能存在并发竞争的场合使用Vector,但Vector内部使用了Synchronized请求锁,比如下面代码:
public String[] createStrings(){
Vector<String> v = new Vector<String>();
for(int i=0;i<100;i++){
v.add(Integer.toString(i));
}
return v.toArray(new String[0]);
}
上述代码中Vector,由于变量v只在createStrings函数中使用,因此他只是一个单纯的局部变量。局部变量是在线程栈上分配的,属于线程私有的数据,因此不可能被其他线程访问。这样的情况下,Vector内部所有的加锁同步是没必要的。如果虚拟机检测到这种情况,就会将这些无用的锁操作去除。
锁消除涉及的一项关键技术为逃逸分析。逃逸分析是观察某一个变量是否会逃出一个作用域。在本例中,变量v显然没有逃出createStrings()函数之外。以此为基础,虚拟机才可以大胆地将变量v内部的加锁操作去除。如果createStrings()返回的不是数组,而是v本身,那么就认为变量v逃逸出了当前函数,也就是说变量v有可能被其他线程访问。如果这样,虚拟机就不能消除变量v中的锁操作。
逃逸分析必须在 -server 模式下进行,可以使用 -XX:+DoEscapeAnalysis 参数打开逃逸分析。使用 -XX:+EliminateLocks 参数可以打开锁消除。
多线程(7)— JDK对锁优化的努力的更多相关文章
- 并发设计模式和锁优化以及jdk8并发新特性
1 设计模式 (1) 单例模式 保证一个类只能一个对象实现.正常的单例模式分为懒汉式和饿汉式,饿汉式就是把单例声明称static a=new A(),系统第一次调用的时候生成(包括调用该类的其他静态资 ...
- Java 虚拟机对锁优化所做的努力
作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...
- 深入理解多线程(五)—— Java虚拟机的锁优化技术
本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...
- Java虚拟机对锁优化所做的努力(读书笔记)
锁偏向 是一种加锁操作的优化手段,他的核心思想是:如果一个线程获得了锁,那么就进入偏向模式,当这个线程再次请求锁时,无须在做任何同步操作,因此在几乎没有锁竞争的场合,偏向锁是比较好的优化效果 ...
- Java并发与多线程与锁优化
前言 目前CPU的运算速度已经达到了百亿次每秒,所以为了提高生产率和高效地完成任务,基本上都采用多线程和并发的运作方式. 并发(Concurrency):是指在某个时间段内,多任务交替处理的能力.CP ...
- Java多线程编程—锁优化
并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...
- java多线程编程——锁优化
并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...
- Java多线程之锁优化策略
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html 锁的优化策略 编码过程中可采取的锁优化的思路有以下几种: 1:减少锁持有时间 例如:对 ...
- Java多线程编程 — 锁优化
阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...
随机推荐
- 【CSP模拟赛】坏天平(数学&思维)
蹭兄弟学校的题目做还不用自己出题的感觉是真的爽 题目描述 nodgd有一架快要坏掉的天平,这架天平右边的支架有问题,如果右边的总重量比左边多太多,天平就彻底坏掉了.现在nodgd手上有n种砝码,质量分 ...
- 制作OpenFOAM计算结果的gif动画【转载】
转载自:http://blog.sina.com.cn/s/blog_6277cbbf0100niqi.html PS:对其中错误地方进行了修正 1.用ParaView将每一帧都输出成图片(File- ...
- JDK8 API文档
API 文档 java SE 8 API 文档 jdk-8-apidocs 在线版 java SE 目录 java SE 6 API文档 Java Platform Standard Edition ...
- 2019SDN上机第4次作业
一.作业要求 1.解压安装OpenDayLight控制器(本次实验统一使用Beryllium版本) 2.启动并安装插件 3.用Python脚本搭建给定的拓扑,并连接OpenDayLight控制器 4. ...
- 开启和关闭oracle数据库中的审计功能
第1步:查看审计功能是否开启?SQL> show parameter audit;NAME TYPE VALUE-- ...
- delphi 二维数组的大小和元素个数问题
type TComplex = record Real : Single; Imag : Single; end; TKArray=array [1..2048,1..2048] of TComple ...
- PHP课程环境安装总结文档
phpStudy的安装 1.找一个硬盘根目录,比如这里我使用E盘,在E盘根目录创建一个php的文件夹,进入php文件夹,如下图所示 2.在步骤1的php文件夹下再建立一个文件夹php_dev,如下图所 ...
- Java 什么是静态内部类
#定义 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类. 有static关键字修饰的内部类. 比如:Pattern类中的Node类. public class Outer { pr ...
- ISO/IEC 9899:2011 条款6.6——常量表达式
6.6 常量表达式 语法 1.constant-expression conditional-expression 描述 2.一个常量表达式可以在翻译期间被计算,而不是在运行时,并且根据情况可以被用于 ...
- Spring MVC 验证表单
在实际工作中,得到数据后的第一步就是检验数据的正确性,如果存在录入上的问题,一般会通过注解校验,发现错误后返回给用户,但是对于一些逻辑上的错误,比如购买金额=购买数量×单价,这样的规则就很难使用注 ...