如果你不想平庸,就请勿进行后退的脚步。同样作为支流的开发语言,Java 也没有进行后退,而是始终在优化提高。更多内容请搜寻关注微信公众号:Different Java
摘要
- 为什么须要锁优化
- 锁的状态
- 偏差锁
- 轻量级锁
- 锁降级
- 锁打消
1. 为什么须要锁优化
synchronized Lock 在 JDK1.6 之前效率低下,起因咱们曾经在乐观锁中讲述过了,因而为了进步锁的效率,JVM 对其进行了优化。
2. 锁的状态
锁优化的过程也是锁状态变更的过程,锁的状态目前有以下几种:
- 无状态锁
- 偏差锁
- 轻量级锁
- 重量级锁
锁的状态是如何标记的,这就须要借助 Java 对象在内存中的存储格局。Java 对象在虚拟机中大抵分为三局部:
- 对象头
- 实例数据
- 对齐填充
对象头中存储对象本身运行时的数据(Mark Word)以及类型指针,而 锁的状态则保留在 Mark Word 中。 因为锁状态的不同,Mark Word 也会不雷同。各种锁状态下的 Mark Word(32 位 JVM)如下:
3. 偏差锁
如果一个线程取得了锁,那么锁就进入偏差模式,此时对象的 Mark Word 也会进入偏差锁模式,当该线程再次申请锁无需执行获取锁操作,省去了大量获取锁的工夫。对于竞争不强烈的场合偏差锁的晋升成果还是很显著的,然而竞争强烈的场合倡议敞开偏差锁,能够应用 -XX:-UseBiasedLocking 此参数敞开偏差锁。
偏差锁的锁定和撤销的简要步骤如下:
4. 轻量级锁
当偏差锁失败时,虚拟机不会立刻挂起线程。它会将对象头部作为指针,指向 持有锁的线程堆栈外部,来判断一个线程是否持有对象锁。如果胜利,则能够进入临界区,失败当前会收缩为重量级锁,然而收缩后,虚拟机还会做最初一次致力优化,那就是自旋锁。
轻量级锁收缩重量级锁的简要步骤如下:
5. 自旋锁
因为以后线程临时无奈取得锁,但何时获取也是未知的。有可能在几个 CPU 时钟周期后便可失去锁,此时虚拟机或进行一次赌注,会让以后线程做几个空循环,在通过若干次循环后如果能够失去锁便进入临界区,如果不能取得锁,则将线程真正从操作系统层面挂起。
6. 锁降级
锁只能降级不能降级,锁降级的具体步骤如下:
7. 锁打消
锁打消是 JVM 运行时通过 JIT 编译来发现不可能存在共享资源竞争的锁,而后将其打消(打消的要害是要借助逃逸剖析),节俭无意义的申请工夫。
本期的 Java 锁优化就介绍到这,我是 shysh95,咱们下期再见!