面试题:Java 中的 synchronized 轻量级锁是否会进行自旋?

在 Java 中,synchronized 的实现涉及到几种不同的锁状态,包括无锁状态、偏向锁、轻量级锁和重量级锁。这些状态之间的转换是根据运行时的并发情况动态调整的。

对于轻量级锁来说,它并不直接涉及自旋的概念。轻量级锁主要通过比较并交换(CAS, Compare-And-Swap)操作来尝试原子地获取锁。

如果当前线程能够成功使用 CAS 操作将对象头中的 Mark Word 更新为指向自己线程栈帧中创建的锁记录(Lock Record),那么该线程就获得了这个锁;否则,表示存在竞争,轻量级锁会膨胀成重量级锁。

然而,与轻量级锁相关的“自旋”概念通常出现在重量级锁的上下文中,这被称为自适应自旋(Adaptive Spinning)。

当一个线程尝试获取已经被其他线程持有的重量级锁时,JVM 可能会让该线程进行短暂的自旋等待(即不断尝试获取锁而不立即进入阻塞状态),以期望持有锁的线程很快释放锁。

这种机制可以减少线程切换的开销,在锁被短时间占用的情况下特别有效。

自适应意味着 JVM 会根据历史数据自动调整每个锁对象的自旋次数,比如上次自旋是否成功获得锁等信息。

因此,总结来说:

  • 轻量级锁:不直接涉及自旋,而是依赖于 CAS 操作来尝试非阻塞地获取锁。
  • 重量级锁:可能会采用自适应自旋策略,允许尝试获取锁的线程在一定条件下自旋等待而不是立刻阻塞。

理解这两者的区别有助于更好地利用 synchronized 关键字提供的同步机制,并根据具体的应用场景选择合适的并发控制策略。

THE END
喜欢就支持一下吧
点赞11 分享