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对锁优化的努力的更多相关文章

  1. 并发设计模式和锁优化以及jdk8并发新特性

    1 设计模式 (1) 单例模式 保证一个类只能一个对象实现.正常的单例模式分为懒汉式和饿汉式,饿汉式就是把单例声明称static a=new A(),系统第一次调用的时候生成(包括调用该类的其他静态资 ...

  2. Java 虚拟机对锁优化所做的努力

    作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...

  3. 深入理解多线程(五)—— Java虚拟机的锁优化技术

    本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...

  4. Java虚拟机对锁优化所做的努力(读书笔记)

    锁偏向      是一种加锁操作的优化手段,他的核心思想是:如果一个线程获得了锁,那么就进入偏向模式,当这个线程再次请求锁时,无须在做任何同步操作,因此在几乎没有锁竞争的场合,偏向锁是比较好的优化效果 ...

  5. Java并发与多线程与锁优化

    前言 目前CPU的运算速度已经达到了百亿次每秒,所以为了提高生产率和高效地完成任务,基本上都采用多线程和并发的运作方式. 并发(Concurrency):是指在某个时间段内,多任务交替处理的能力.CP ...

  6. Java多线程编程—锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  7. java多线程编程——锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  8. Java多线程之锁优化策略

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html  锁的优化策略 编码过程中可采取的锁优化的思路有以下几种: 1:减少锁持有时间 例如:对 ...

  9. Java多线程编程 — 锁优化

      阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...

随机推荐

  1. Tkinter 之记事本项目实战

    一.效果图 二.文件 链接:https://pan.baidu.com/s/1CUkfWpfH8t2GSJyy5hYv-A 提取码:5yvn 后续可能做一些功能扩展,有需要源码的可以评论联系我!!!

  2. centos7--zabbix3.4微信报警

    1.申请企业微信 1.1 注册企业微信的地址 https://qy.weixin.qq.com/ 1.2 按照提示进行填写 1.3 完善个人信息: 1.4 创建应用 根据提示创建应用: 1.5 筛出重 ...

  3. UDP如何实现可靠传输

    概述 UDP不属于连接协议,具有资源消耗少,处理速度快的优点,所以通常音频,视频和普通数据在传送时,使用UDP较多,因为即使丢失少量的包,也不会对接受结果产生较大的影响. 传输层无法保证数据的可靠传输 ...

  4. Java设计模式之三建造者模式和原型模式

    建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.简单的来说就是将一个复杂的东西 ...

  5. csapp网络编程初学笔记

    csapp网络编程初学笔记 客户端-服务器编程模型 每个网络应用都是基于客户端-服务器模型,服务器管理某种资源,并且通过操作来为它的客户提供某种服务 客户端-服务器模型中的基本操作是transacti ...

  6. [spring-boot] 配置 MySQL

    spring-boot项目 配置MYSQL驱动 maven pom文件中增加依赖 <!-- MYSQL驱动 --> <dependency> <groupId>my ...

  7. 文献阅读 | Benchmarking single cell RNA-sequencing analysis pipelines using mixture control experiments

    资源: sci-hub paper CellBench package - github CellBench_data - code for the paper 现在单细胞领域的突出问题就是工具过多, ...

  8. 【mybatis源码学习】与spring整合Mapper接口执行原理

    一.重要的接口 org.mybatis.spring.mapper.MapperFactoryBean MapperScannerConfigurer会向spring中注册该bean,一个mapper ...

  9. socat管理haproxy配置 ssh-keygen -N '' -t rsa -q -b 2048

    socat管理haproxy配置   haproxy是可以通过socat命令管理haproxy.cfg文件的:1.安装socat yum install socat -y 2.配置haproxy.cf ...

  10. 关于Kubernetes Master高可用的一些策略

    关于Kubernetes Master高可用的一些策略 Kubernetes高可用也许是完成了初步的技术评估,打算将生产环境迁移进Kubernetes集群之前普遍面临的问题. 为了减少因为服务器当机引 ...