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

1、 锁偏向

锁偏向是一种针对加锁操作的优化手段。

如果一个线程获得了锁,那么锁就进入偏向模式。当这个线程再次请求锁时,无须再做任何同步操作。这样就节省了大量有关锁申请的操作,从而提高了程序性能。因此,对于几乎没有锁竞争的场合,偏向锁有比较红啊的优化效果,因为连续多次极有可能是同一个线程请求相同的锁。而对于锁竞争比较激烈的场合,其效果不佳。因为在竞争激烈的场合,最有可能的情况是每次都是不同的线程来请求相同的锁。

2、 轻量级锁

如果偏向锁失败,即上一个请求的锁的线程和这个线程不是同一个。偏向锁失败意味者不能避免做同步操作。此时,虚拟机并不会立即挂起线程。他会使用一种成为轻量级锁的优化手段。 轻量级锁的操作也很方便,它只是简单地将对象头部作为指针,指向蚩尤锁的线程堆栈的内部,来判断一个线程是否持有对象锁。 如果线程获得轻量级锁成功,则可以顺利进入临界区。如果轻量级锁失败,则表示其他线程抢先争夺了锁,那么当前线程的锁请求就会膨胀为重量级锁。

3、 自选锁

锁膨胀后,虚拟机为了避免线程真实地在操作系统层面挂起,虚拟机还会在做最后的努力–自选锁。由于当前线程暂时无法获得锁,但是什么时候可以获得锁是一个未知数。也许在CPU几个时钟周期后,就可以得到锁。如果这样,简单粗暴的挂起线程可能是一种得不偿失的操作,因此系统会进行一次赌注:它会假设在不久的将来,线程可以得到这把锁。因此虚拟机让当前线程做个空循环,在经过若干次循环后,如果可以得到锁,那么就顺利进入临界区。如果还不能得到锁,才会真实地将线程在操作系统层面挂起。

4、 锁消除

锁消除是一种更彻底的锁优化。Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁。通过锁消除,可以节省毫无意义的请求锁时间。

下面这种这种情况,我们使用vector, 而vector内部使用了synchronize请求锁。

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[]{});
}

由于V只在函数 createStrnigs 中使用,因此它只是一个单纯的局部变量。局部变量是在线程栈上分配的,属于线程私有额数据,因此不可能被其他线程访问。所以,在这种情况下,Vector内部所有加锁同步都是没有必要的。如果虚拟机检测到这种情况,就会将这些无用的锁操作去除。

锁消除涉及的一项关键技术为逃逸分析。所谓逃逸分析就是观察某一个变量是否会逃出某一个作用域。在本例中,变量v显然没有逃出createString 函数之外。以此为基础,虚拟机才可以大胆的将v内部的加锁操作去除。如果createStrings 返回的不是String数组,而是v本身,那么就认为变量v逃逸出了当前函数,也就是说v有可能被其他线程访问。如是这样,虚拟机就不能消除v中的锁操作。

逃逸分析必须在 -server 模式下进行,可以使用 -XX:DoEscapeAnalysis 参数打开逃逸分析,使用 -XX:+EliminateLocks 参数可以打开锁消除。

本文摘自《Java高并发程序设计》一书。

教程:史上最强 Spring Boot & Cloud 教程汇总

工具:推荐一款在线创作流程图、思维导图软件

Java 虚拟机对锁优化所做的努力的更多相关文章

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

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

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

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

  3. Java虚拟机的锁优化

    1 锁偏向.当现成请求一个对象锁时,如果获得锁,则该对象锁进入偏向模式,当该线程再次请求该对象的锁时,无需再做任何同步操作. 可通过在Java虚拟机中开启参数-XX:+UseBasedLock开启偏向 ...

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

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

  5. java虚拟机和内存优化总结

    前一段时间总结了spring和springmvc相关的知识,面试中常问到的除了这些基本的框架之外,还有底层的基础知识,比如与java虚拟机相关的知识点,这一部分也是面试中经常问到的,在面试中高级jav ...

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

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

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

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

  8. HotSpot虚拟机的锁优化

    面试中多次被问到synchronized关键字的实现原理,一直认为仅是monitorenter与monitorexit两条指令而已,原来底层涉及到多种锁优化策略,包括:自旋锁,轻量锁,偏向锁. 1.自 ...

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

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

随机推荐

  1. jira6.3.6创建问题不自动发邮件通知的问题

    装完jira6.3.6后,设置好邮件服务器,测试没有问题.但是创建问题不自动发邮件提示用户.折腾了大半天,请教了一位大神,终于搞定.步骤是: agile->系统->用户界面->用户缺 ...

  2. linux学习第十九天 (Linux就该这么学) 结课了

    今天最后一天课程了,结课了,还有点舍不得那,在些也祝 李老师 事业蒸蒸日上,超来超好, 今天内容是部署了 LNMP 部署动态网站环境(linux  +nginx+mysql+php) 安装文件挺别多, ...

  3. Python Day 9

    阅读目录: 内容回顾 内存管理 ##内容回顾 #文件处理 #1.操作文件的三步骤 -- 打开文件:硬盘的空间被操作系统持有 | 文件对象被应用程序持续 -- 操作文件:读写操作 -- 释放文件:释放操 ...

  4. P1081 开车旅行(Not Finish)

    https://www.luogu.org/problemnew/show/P1081

  5. JavaScript中Object.keys用法

    Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组. var data={a:1,b:2,c:9,d:4,e:5}; console.log(data);//{a: 1, ...

  6. Hibernate中的实体规则、对象状态和进阶-一级缓存

    一.hibernate中的实体规则 1.实体类创建的注意事项 2.主键类型 3.主键生成策略 (1)代理主键 (2)自然主键 二.hibernate中的对象状态 1.对象分为三种状态 2.三种状态的转 ...

  7. sjms-1 面向对象

    面向对象设计 先设计架构,然后去完成相应模块和类 设计模式:对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案.每一个设计模式系统地命名.解释和评价了面向对象系统中一个重要的和重复出现的设计 ...

  8. 解决ssh连接慢,挂起在SSH2_MSG_SERVICE_ACCEPT信息之后很久的问题

    问题现象:无论是ssh 还是 scp 都会连接很久才提示输认证信息(注意:是连接慢) 如本机IP:192.168.18.208 (Hostname: ThinkPad) 目标主机:192.168.18 ...

  9. Normalize.css & Reset

    Normalize.css: try to keep the style consistent in every browser. Reset: clear style in every browse ...

  10. 【转载】java定义二维数组问题。分清数组与集合的区别

    出处: 度娘知道 答案由用户{ heitianba }提供. Q: int a[][] = new int[3][2];  a[0] = {1,6};  报错:第二句是非法表达式.为什么? A: in ...