锁优化技术(HotSpot虚拟机而言)包括适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁等。这些技术都是为了在线程之间更高效地共享数据以及解决竞争问题,从而提升程序效率。数组
若是线程获取不到锁,第一时间不是去切换系统态进行等待,而是作一个循环操做,去等到锁的释放,循环到必定的次数终止循环,调入系统调用。为了让线程等待,而不是阻塞,让线程执行一个忙循环(自旋),这就是自旋锁。多线程
自旋锁的优化主要是为了减小了线程切换带来的消耗。app
自旋锁适合那些线程占用锁时间短的场景。性能
JDK1.6加入了自适应自旋锁。顾名思义,若是在同一个锁对象上,自旋等待刚刚成功得到过锁,而且持有锁的线程正在运行,那么虚拟机就会认为此次自旋也颇有可能再次成功,并将自旋等待时间延长。若是对于某个锁,自旋不多成功,那么在以后获取该锁时可能会放弃不自旋直接挂起线程。优化
指虚拟机即时编译器在运行时,对一些代码上要求同步,可是被检测到不可能存在共享数据竞争时,把锁进行消除。操作系统
锁消除的主要判断依据来源于逃逸分析的数据支持,若是判断在一段代码中,堆上的全部数据都不会逃逸出去从而被其余线程访问到,那就能够把它们当作栈上数据对待,认为它们是线程私有的,同步加锁就无需进行。线程
若是一系列的连续动做都对同一对象反复加锁和解锁,甚至加锁操做时出如今循环体中的,那即便没有线程竞争,频繁地进行互斥同步操做也会致使没必要要的性能损耗,好比连续的append()方法。指针
在说轻量级锁和偏向锁以前,咱们要先了解一下HotSpot虚拟机中对象的对象头。对象
HotSpot虚拟机的对象头分为两部分信息:编译器
因此,咱们来看一下对象头的Mark Word中的存储内容有哪些?
存储内容 | 标志位 | 状态 | 用处 |
对象哈希码,对象分代年龄 | 01 | 未锁定 | 状态 |
指向锁记录的指针 | 00 | 轻量级锁定 | 状态 |
指向重量级锁的指针 | 10 | 膨胀 | 状态 |
空,不须要记录信息 | 11 | GC标记 | 状态 |
偏向线程ID,偏向时间戳、对象分代年龄 | 01 | 可偏向 | 状态 |
什么是CAS操做?
CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。简单来讲,CAS整个比较并替换的操做是一个原子操做。
他的意思是在没有多线程竞争的前提下,减小传统的重量级锁使用操做系统互斥量产生的消耗
加锁过程:
解锁过程:
提高程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”。
若是没有竞争,轻量级锁使用CAS操做避免了使用互斥量的开销。
但若是存在锁竞争,除了互斥量的开销外,还额外发生了CAS操做,所以在有竞争的状况下,轻量级锁会比传统的重量级锁更慢。
消除数据在无竞争状况下的同步原语,进一步提升程序的运行性能。简单来讲就是**在无竞争的状况下把整个同步都消除掉,连CAS操做都不作。**就是说当一个线程率先获取到这个锁后,若是该锁没有被其余线程获取,那么持有偏向锁的线程将永远不须要同步。
能够提升带有同步但无竞争的程序性能
和轻量级锁同样,若是这个同步块可能不少时候都是多个线程同时访问的话,那么偏向锁甚至会增长时耗
JVM对锁进行了优化,包括自旋锁(自适应自旋锁)、锁粗化、轻量级锁、偏向锁。然后二者会由于竞争的多少而产生性能的变化。