锁升级过程中的两次自旋 面试重点

1.什么是自旋

        自旋(Spinning)是一种在多线程环境下等待锁的技术。当一个线程尝试获取某个已被其他线程持有的锁时,该线程不会立即进入阻塞状态,而是会在一个循环中持续检查锁的状态,即“自旋”。如果在这个过程中锁被释放了,那么该线程就可以立即获取锁,从而避免了线程阻塞和上下文切换的开销。

2.锁升级过程的第一次自旋

        第一次自旋发生在synchronized获取轻量级锁时,即当一个线程尝试获取一个被其他线程持有的轻量级锁时,它会自旋等待锁的持有者释放锁。
        在OpenJDK8中,轻量级锁的自旋默认是开启的,最多自旋15次,每次自旋的时间逐渐延长。如果15次自旋后仍然没有获取到锁,就会升级为重量级锁。

3.锁升级过程中的第二次自旋

        第二次自旋发生在synchronized 轻量级锁升级到重量级锁的过程中。即当一个线程尝试获取一个被其他线程持有的重量级锁时,它会自旋等待锁的持有者释放锁。
        在OpenJDK8中,默认情况下不会开启重量级锁自旋。如果线程在尝试获取重量级锁时,发现该锁已经被其他线程占用,那么线程会直接阻塞,等待锁被释放。如果锁被持有时间很短,可以考虑开启重量级锁自旋,避免线程挂起和恢复带来的性能损失。

4.自适应自旋

        在JDK6中之后的版本中,JVM引入了自适应的自旋机制。该机制通过监控轻量级锁自旋等待的情况动态调整自旋等待的时间。
        如果自旋等待的时间很短,说明锁的竞争不激烈,当前线程可以自旋等待一段时间,避免线程挂起和恢复带来的性能损失。如果自旋等待的时间较长,说明锁的竞争比较激烈,当前线程应该及时释放CPU资源,让其他线程有机会执行。
        自适应的自旋实现在ObjectSynchronizer::FastHashCode(函数中。该函数会根据轻量级锁自旋等待的情况,调整自旋等待的时间。

5.自旋的实现

在OpenJDK 8的源码中,synchronized的升级过程中涉及到了多次自旋操作,其中包括:
        第一次自旋:在尝试获取轻量级锁失败后,线程会进行自旋,使用CAS操作去尝试获取锁。这里的
自旋并没有使用while循环,而是使用了C++的inline函数,如ObjectSynchronizer::FastLock0)。
        第二次自旋:在尝试获取重量级锁失败后,线程会进行自旋,等待拥有锁的线程释放锁。这里的自
旋同样使用了C++的inline函数,如ObjectSynchronizer…:FastUnlock()。
        自适应自旋:在尝试获取轻量级锁时,线程会进行自旋,等待拥有锁的线程释放锁。但这里的自旋不是固定次数的,而是根据前一次自旋的时间和成功获取锁的概率进行自适应调整。这里的自旋实现在C++的Thread.inline.hpp中,如Thread::SpinPause(。
        需要注意的是,虽然这些自旋操作并没有使用while循环实现,但其本质上都是在不断尝试获取锁或等待锁的过程中循环执行的。这些循环操作使用的是各种内建函数、指令集和C++的语法特性实现,能够更高效地执行自旋操作,从而提升锁的性能。

相关推荐

  1. 升级过程 面试重点

    2024-07-19 02:44:03       23 阅读
  2. 深入解析 Golang

    2024-07-19 02:44:03       53 阅读
  3. skynet - spinlock 简单

    2024-07-19 02:44:03       32 阅读
  4. Synchronized升级过程

    2024-07-19 02:44:03       45 阅读
  5. 面试——数据库升级(Lock Escalation)机制

    2024-07-19 02:44:03       33 阅读
  6. C++实战篇(一)——使用

    2024-07-19 02:44:03       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 02:44:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 02:44:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 02:44:03       58 阅读
  4. Python语言-面向对象

    2024-07-19 02:44:03       69 阅读

热门阅读

  1. electron 应用的生命周期

    2024-07-19 02:44:03       23 阅读
  2. SQL基础

    2024-07-19 02:44:03       21 阅读
  3. 【Unity C#优化】业务逻辑代码方面的优化

    2024-07-19 02:44:03       21 阅读
  4. 【Linux】微基准测试

    2024-07-19 02:44:03       21 阅读
  5. AI发展下的伦理挑战,应当如何应对?

    2024-07-19 02:44:03       19 阅读
  6. 软件测试有光明的未来

    2024-07-19 02:44:03       20 阅读
  7. 1、PostgreSQL安装

    2024-07-19 02:44:03       20 阅读
  8. 数组reduce的众多用法

    2024-07-19 02:44:03       21 阅读
  9. 泛型+反射

    2024-07-19 02:44:03       18 阅读