HotSpot虚拟机各种锁优化技术

原创 2018年04月15日 18:19:16

高效并发是从JDK1.5到JDK1.6的一个重要改进,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如自旋,适应性自旋,锁消除、锁粗化、轻量级锁和偏向锁等,这些技术都是为了在线程之间更高效地共享数据,以及解决竞争问题,从而提高程序的执行效率。

自旋锁和自适应自旋

如果物理机器有一个以上的处理器,能让两个或以上的线程同时并行执行,我们就可以让后面请求锁的那个线程“稍等一下”,但并放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只需让线程执行一个忙循环(自旋),这项技术就是所谓的自旋锁。
自旋锁在JDK 1.4.2 中就已经引入,只不过默认是关闭的,可以使用-XX:UseSpinning参数来开启,在JDK 1.6中就已经改为默认开启了。自旋等待不能代替阻塞,且先不说对处理器数量的要求,自旋等待本身虽然避免了线程切换的开销,但它是要占用处理器时间的,因此,如果锁被占用的时间很短,自旋等待的效果就会非常好,反之,如果锁被占用的时间很长,那么自旋的线程只会白白消耗处理器资源,而不会做任何有用的工作,反而会带来性能上的浪费。因此,自旋等待的时间必须要有一定的限度,如果自旋超过了限定的次数仍然没有成功获得锁,就应当使用传统的方式挂起线程了。自旋次数的默认值是10次。
在JDK 1.6 中引入了自适应自旋锁。自适应意味着自旋的时间不再固定了,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也很有可能再次成功,进而它将允许自旋等待持续相对更长的时间,比如100个循环。另外,如果对于某个锁,自旋很少成功获得过,那在以后要获取这个锁时将可能省略点自旋过程,以避免浪费处理器资源。

锁消除

锁消除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除。锁消除的主要判定依据来源于逃逸分析的数据支持,如果判断在一段代码中,堆上的所有数据都不会逃逸出去从而被其他线程访问到,那就可以把它们当做栈上数据对待,认为它们是线程私有的,同步加锁自然就无须进行。

锁粗化

原则上,我们在编写代码的时候,总是推荐将同步块的作用范围限制得尽量小—只在共享数据的实际作用域中才进行同步,这样是为了使得需要同步的操作数量尽可能变小,如果存在竞争,那等待锁的线程也能尽快拿到所。大部分情况下,上面的原则都是正确的,但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作都是出现在循环体中,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗。

轻量级锁

轻量级锁是JDK 1.6 之中加入的新型锁机制,它名字中的“轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的,因此传统的锁机制就称为“重量级”锁。首先需要强调一点的是,轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。
在代码进入同步块的时候,如果此同步对象没有被锁定,虚拟机首先将在当前线程的栈针中建立一个名为锁记录的控件,用于存储对象目前的Mark Word的拷贝。然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针。如果这个更新成功了,那么这个线程就用了该对象的锁。
注意:要理解轻量级锁,必须要理解HotSpot虚拟机对象的内存布局(将在下一篇文章介绍)
轻量级锁能提升程序同步性能的一依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销,但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。

偏向锁

偏向锁也是在JDK 1.6 中引入的一向锁优化,它的目的是消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。它的意思是这个锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011363729/article/details/79951564

Java锁优化

锁优化技术: 适应性自旋(Adaptive Spinning)、锁消除(Lock Elimination)、锁粗化(Lock Coarsening)、轻量级锁(Lightweight Locking)...
  • tanga842428
  • tanga842428
  • 2016年08月14日 09:04
  • 865

对Java HotSpot 性能引擎的深入研究

 对Java HotSpotTM 性能引擎的深入研究1. 序言 Java HotSpotTM 性能引擎正式发布于1999年4月27日。它远远不只是一个性能调整引擎,而是一个实际意义上的Java虚拟机(...
  • cherami
  • cherami
  • 2001年11月04日 16:28
  • 3692

java虚拟机对锁的优化之锁粗化和锁消除

锁消除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除。锁消除主要判定依据来源于逃逸分析的数据支持 锁粗化,如果虚拟机探测到有这样一串零碎的...
  • xuqiaobo
  • xuqiaobo
  • 2016年09月14日 09:29
  • 955

什么是HotSpot

没错,Java是解释语言,但并不意味着它一定被解释执行。早期 的虚拟机确实一条一条指令解释执行,但人们发现这样效率太低, 不满足各种要求,因此出现了许多其它虚拟机,如JIT的虚拟机。 HotSpot也...
  • zhangjianying
  • zhangjianying
  • 2006年10月08日 21:24
  • 9138

[深入理解Java虚拟机]第十三章 线程安全与锁优化-锁优化

高效并发是从JDK 1.5到JDK 1.6的一个重要改进,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋(Adaptive Spinning)、锁消除(Lo...
  • qilixiang012
  • qilixiang012
  • 2015年11月08日 23:50
  • 718

HotSpot虚拟机

注:如其中有不懂的名词,下面有名词解释 1、对象的创建(限于普通Java对象,不包括数组和Class对象等) (1)检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是...
  • jin343229836
  • jin343229836
  • 2017年03月14日 18:05
  • 627

jvm HotSpot虚拟机主要参数表

本参数表以JDK 1.6为基础编写,JDK 1.6的HotSpot虚拟机有很多非稳定参数(Unstable Options,即以-XX:开头的参数,JDK 1.6的虚拟机中大概有660多个),使用-X...
  • qilixiang012
  • qilixiang012
  • 2015年11月09日 00:02
  • 973

【学习笔记】Java虚拟机(三)HotSpot虚拟机探秘

HotSpot虚拟机探秘 1、对象的创建 ① 虚拟机遇到new指令时,首先检查这个指令参数是否能在常量池中定位到一个类的符号引用 ,并检查其是否已被加载、解析和初始化过,如果没有则先进行类的加载。...
  • tcchenlz
  • tcchenlz
  • 2018年02月17日 09:44
  • 31

Java虚拟机--锁在应用层的优化思路(十四)

减少锁持有时间 问题描述:锁竞争时,单个线程对锁的持有时间与系统性能有着直接的关系。线程持有锁的时间很长,相对的,锁的竞争程度也就越激烈。在程序开发中,应该尽可能减少对某个锁的占有时间,以...
  • qq_33301113
  • qq_33301113
  • 2017年04月18日 15:49
  • 434

深入理解Java虚拟机----(十一)线程安全与锁优化

线程安全     为了深入讨论,不把线程安全当做非真即假的概念,我们把它分为5个层次。 不可变:不可变的数据是线程安全的。例如前面提到的final,被final修饰的基础数据类型,被正确构...
  • wl6965307
  • wl6965307
  • 2016年02月12日 17:05
  • 1042
收藏助手
不良信息举报
您举报文章:HotSpot虚拟机各种锁优化技术
举报原因:
原因补充:

(最多只允许输入30个字)