多线程(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多线程编程 — 锁优化
阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...
随机推荐
- ElasticSearch : 基础简介
1.安装 我用的docker安装,这个用起来比较方便,我是在腾讯云部署的docker,具体的过两天总结一下 安装: docker pull elasticsearch 运行: docker run - ...
- GO获取随机数
使用的"math/rand"包. 基本随机数 a := rand.Int() b := rand.Intn(100) //生成0-99之间的随机数 fmt.Println(a) f ...
- 基于Redis的分布式锁到底安全吗(下)?
2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...
- various system release [online]
1. 金丝雀发布 Canary 简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据. 金丝雀发布,一 ...
- openwrt共享打印机需要安装哪几个文件
opkg updateopkg install luci-app-p910ndopkg install kmod-usb-printer
- HmacSHA256摘要算法
mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥. 甲乙双方进行数据交换可以采取如下流程完成 ...
- Flutter -------- Http库 网络请求封装(HttpController)
http库 再次封装的网络请求类 HttpController 1.添加依赖 dependencies: http: ^0.12.0 #latest version 2.导入库 import 'pac ...
- 002 centos7中遇到的问题
在关机的时候,发现输入密码之后竟然报错了,然后确认普通用户的密码没有问题.下面是处理方式. 一:问题 1.问题 当在终端执行sudo命令时,系统提示“caojun is not in the sudo ...
- mysql 安装参考
https://blog.csdn.net/qq_38756992/article/details/84929787 https://www.cnblogs.com/joyny/p/10991194. ...
- 002-06-RestTemplate-请求示例-form、json、multipart、okhttp3
一.概述 请求示例集合 服务端:https://github.com/bjlhx15/common-study.git 中的 http-client-webserver 服务端:RequestBody ...