Java偏向锁实现原理(Biased Locking)

阅读本文的读者,须要对Java轻量级锁有必定的了解,知道lock record, mark word之类的名词。能够参考个人一篇博文:Java轻量级锁原理详解(Lightweight Locking) 多线程

Java偏向锁(Biased Locking)是Java6引入的一项多线程优化。它经过消除资源无竞争状况下的同步原语,进一步提升了程序的运行性能。 性能

轻量级锁也是一种多线程优化,它与偏向锁的区别在于,轻量级锁是经过CAS来避免进入开销较大的互斥操做,而偏向锁是在无竞争场景下彻底消除同步,连CAS也不执行(CAS自己仍旧是一种操做系统同步原语,始终要在JVM与OS之间来回,有必定的开销)。 优化

所谓的无竞争场景,举个例子,就是单线程访问带同步的资源或方法。 spa

 

偏向锁实现原理

偏向锁,顾名思义,它会偏向于第一个访问锁的线程,若是在接下来的运行过程当中,该锁没有被其余的线程访问,则持有偏向锁的线程将永远不须要触发同步。
若是在运行过程当中,遇到了其余线程抢占锁,则持有偏向锁的线程会被挂起,JVM会尝试消除它身上的偏向锁,将锁恢复到标准的轻量级锁。(偏向锁只能在单线程下起做用) 操作系统

经过下图能够更直观的理解偏向锁: 线程

这张图,省略了轻量级锁相关的几处步骤,将关注点更多地聚焦在偏向锁的状态变化上。
偏向模式和非偏向模式,在下面的mark word表中,主要体如今thread ID字段是否为空。 图片

挂起持有偏向锁的线程,这步操做相似GC的pause,但不一样之处是,它只挂起持有偏向锁的线程(非当前线程)。 内存

在抢占模式的橙色区域说明中有提到,指向当前堆栈中最近的一个lock record(在轻量级锁原理一文有讲到,lock record是进入锁前会在stack上建立的一分内存空间)。
这里提到的最近的一个lock record,其实就是当前锁所在的stack frame上分配的lock record。
整个步骤是从偏向锁恢复到轻量级锁的过程。 资源

偏向锁也会带来额外开销

在JDK6中,偏向锁是默认启用的。它提升了单线程访问同步资源的性能。
但试想一下,若是你的同步资源或代码一直都是多线程访问的,那么消除偏向锁这一步骤对你来讲就是多余的。事实上,消除偏向锁的开销仍是蛮大的。 get

因此在你很是熟悉本身的代码前提下,大可禁用偏向锁 -XX:-UseBiasedLocking 。