简介
在Java并发编程中,synchronized
关键字是实现线程同步的一种常见机制。从JDK 1.6开始,为了提高性能,Java虚拟机(JVM)对synchronized
进行了优化,引入了锁升级的概念。锁升级包括从无锁状态到偏向锁、轻量级锁,最终可能升级为重量级锁的过程。本文将详细解析这一过程及其背后的原理。
正文
1. 锁升级的必要性
在多线程环境中,共享资源的同步访问是保证数据一致性的关键。synchronized
通过锁机制来实现这一目标。然而,在高并发场景下,传统的重量级锁由于涉及用户态与内核态的切换,性能开销较大。因此,JVM引入了锁升级机制,以适应不同的并发场景,减少性能损耗 1。
2. 锁的四种状态
锁的状态从低到高依次为:无锁、偏向锁、轻量级锁和重量级锁。锁状态的升级是单向的,即从低级别状态升级到高级别状态,不可逆 2。
2.1 无锁
无锁状态是指没有对资源进行锁定,所有线程都可以访问资源,但需要不断检查执行过程中资源是否被其他线程修改。
2.2 偏向锁
偏向锁假设大多数锁在整个生命周期内只被一个线程访问。当线程首次访问同步代码块时,JVM会将对象头的Mark Word复制到线程栈中的锁记录,并标记为偏向模式。如果线程再次访问,无需进行额外同步操作,直接进入同步块 3。
2.3 轻量级锁
当有其他线程尝试访问偏向锁时,如果原持有偏向锁的线程仍在执行或未释放锁,JVM会尝试将偏向锁升级为轻量级锁。轻量级锁通过CAS操作尝试获取锁,如果失败,会进行一定次数的自旋,如果自