java中锁的状态共有四种:无锁状态、偏向锁、轻量级锁、重量级锁
1 锁升级
随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级到重量级锁。但是锁的升级是单向的,不会出现降级的情况。
轻量级锁的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用产生的性能消耗。轻量级锁适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一个锁的情况,就会导致轻量级锁升级到重量级锁。
2 偏向锁
对于绝大部分锁,在整个同步周期内不仅不存在竞争,而且总由同一线程多次获得。
偏向锁的目的是在某个线程获得锁之后,消除这个线程锁重入(CAS)的开销,看起来让这个线程得到了偏护。
在一些情况下总是同一线程多次获得锁,此时第二次再重新做CAS修改对象头中的Mark Word这样的操作,有些多余。所以就有了偏向锁,只需要检查是否为偏向锁、锁标识为以及ThreadID即可,只要是同一线程就不再修改对象头。其目的为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径。
3 轻量级锁
轻量级锁,其性能提升的依据是对于绝大部分的锁,在整个生命周期内都是不会存在竞争的,如果没有竞争,轻量级锁就可以使用 CAS 操作避免互斥量的开销,从而提升效率。
轻量级锁适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一个锁的情况,就会导致轻量级锁升级到重量级锁。
4 重量级锁
Synchronized是通过对象内部的一个监视器(monitor)实现的,监视器本身又是依赖于操作系统的Mutex Lock实现的,操作系统之间的线程切换需要由用户态转换到核心态,成本非常高,因此Synchronized效率比较低。