锁的状态总共四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级到重量级锁(但是锁的升级是单向的,也就是说只能从低级到高级,不会出现锁降级)。JDK1.6中默认开启偏向锁和轻量级锁的,我们也可以通过-XX:-UseBiasedLocking来禁用偏向锁。
偏向锁
- 定义:
Java6引入的一项多线程优化。它通过消除无竞争情况下的同步原语,进一步提高程序的运行性能。这里所谓的无竞争场景指的是单线程访问带同步的资源或方法。
- 实现原理:
偏向锁,顾名思义,它会偏向第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步。如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会尝试消除它身上的偏向锁,将锁恢复到标准的轻量级锁。
- 具体流程:
- 评价
在JDK6中,偏向锁是默认启用的。它提高了单线程访问同步资源的性能。但如果你的同步资源或代码一直都是多线程访问的,那么消除偏向锁这一步骤对此时多余的。事实上,消除偏向锁的开销还是蛮大的,因此,我们可以通过-XX:-UseBiasedLocking来禁用偏向锁。
轻量级锁
- 定义:
轻量级锁本意是为了减少多线程进入互斥的状态,并不是要代替互斥。它利用CPU原语Compare-Add-Swap(CAS),尝试在进入互斥体前,进行补救。
- 具体实现流程
- 轻量级锁与偏向锁的区别
轻量级锁也是一种多线程优化,它与偏向锁的区别在于,轻量级锁是通过CAS来避免进入开销较大的互斥操作,而偏向锁是在无竞争场景下完全消除同步,连CAS也不执行(CAS本身仍旧是一种操作系统同步原语,始终要在JVM与OS之间来回,有一定的开销)。
网友评论