1. 锁级别 - 偏向锁:这是一种最乐观的锁策略。当一段同步代码一直被一个线程访问时,就会使用偏向锁。它会在对象头记录获取锁的线程ID,下次该线程进入同步块时,只需要检查对象头的线程ID是否是自己,若是则无需进行CAS(比较并交换)操作获取锁,直接进入同步块,这样可以减少不必要的性能开销。 - 轻量级锁:当有其他线程竞争偏向锁时,偏向锁会升级为轻量级锁。轻量级锁主要是通过自旋(即线程不断地循环检查锁是否可用)来获取锁。它假设线程持有锁的时间很短,在短时间内其他线程可以通过自旋等待获取锁,而不是使线程进入阻塞状态,因为线程阻塞和唤醒的开销较大。 - 重量级锁:如果自旋一定次数后(这个次数可以通过JVM参数调整)仍然无法获取锁,或者同时竞争锁的线程较多,轻量级锁会升级为重量级锁。重量级锁会使线程进入阻塞状态,等待操作系统的调度,涉及到用户态和内核态的切换,开销比较大。 2. 锁升级过程 - 最初,对象没有被锁定时,处于无锁状态。当一个线程访问同步块时,JVM会尝试使用偏向锁,将对象头的部分空间标记为偏向模式,并记录该线程的ID。 - 如果有其他线程尝试访问这个被偏向的对象,会检查偏向锁的持有线程是否还在使用。如果不在使用(比如已经结束),则新线程可以获取偏向锁;如果还在使用,就会将偏向锁升级为轻量级锁。 - 轻量级锁在多个线程竞争的情况下,会先通过自旋等待锁释放。当自旋达到一定次数后仍未获取到锁,或者等待的线程数量超过一定阈值(如CPU核数的一半),轻量级锁就会升级为重量级锁。一旦升级为重量级锁,等待锁的线程会被阻塞,直到持有锁的线程释放锁。

相关推荐

牛客网
牛客网在线编程
牛客网题解
牛客企业服务