深入理解Thread.sleep(0)的作用

 更新时间:2025年09月16日 10:58:17   作者:在下uptown  
本文主要介绍了深入理解Thread.sleep(0)的作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Thread.sleep

先回顾一下Thread.sleep(n)方法的用法,sleep只是去休眠n毫秒的时间,当前对象并没有释放掉锁,与Object.wait()方法最大的区别就在这,wait方法会释放掉锁,而sleep不会。

如此看来sleep(n)中的n是休眠n毫秒,那么n=0的时候理论上说毫无意义,但有时候阅读源码的时候又能看到这句。写中间件的大佬岂能犯这种错误。且听我细细道来

垃圾回收

还是要从垃圾回收说起,刚开始背垃圾回收八股文的时候根本都没想过JVM在什么时候回收辣鸡,直到练习时长两年班之后,在某个公众号推文上才知道,JVM有一个安全区域和安全点 safepoint的概念。

其实不难理解,程序跑着跑着代码里一个虚引用还没来及用呢,JVM突然回收直接给干没了,那肯定会出大问题。所以说要有一个合适的时机去做gc。

程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为"安全点(Safepoint)"

如何在GC发生时,检查所有线程都跑到最近的安全点停顿下来呢?

  1. 抢先式中断:(目前没有虚拟机采用了) 首先中断所有线程。如果还有线程不在安全点,就恢复线程,让线程跑到安全点。
  2. 主动式中断: 设置一个中断标志,各个线程运行到SafePoint的时候主动轮询这个标志,如果中断标志为真,则将自己进行中断挂起。

安全区域是指一段代码片中,引用关系不会发生变化在这个区域任何地方GC都是安全的,安全区域可以看做是安全点的一个扩展。线程执行到安全区域的代码时,首先标识自己进入了安全区域,这样GC时就不用管进入安全区域的线程了,线层要离开安全区域时就检查JVM是否完成了GC Roots枚举,如果完成就继续执行,如果没有完成就等待直到收到可以安全离开的信号

安全点完美的解决了如何进入GC问题,实际情况可能比这个更复杂,但是如果程序长时间不执行,比如线程调用的sleep方法,这时候程序无法响应JVM中断请求这时候线程无法到达安全点,显然JVM也不可能等待程序唤醒,这时候就需要安全区域了。

sleep(0)

理解了程序垃圾回收的时机再回过头来就不难理解sleep(0)的作用了,除了主动放弃调度之外,可以简单的理解为程序不是任意时刻都能gc,需要程序跑到safepoint点,而native方法执行以后就会插入一个safepoint,此时线程在执行JVM以外的代码不能对JVM的执行状态做修改,所以JVM进入safepoint可以忽略此线程。

也就是说sleep(0)的作用:

  1. 是主动让出cpu调度提升系统调度性能
  2. 是使系统进入safepoint标记gc。

使用场景:

Thread.sleep(0) 的使用场景非常有限,通常只在以下情况下考虑:

  • 测试或调试: 在多线程测试或调试中,可以使用 Thread.sleep(0) 来强制触发线程切换,以便观察不同线程的执行顺序或行为。
  • 某些底层优化: 在极少数情况下,某些底层代码可能会使用 Thread.sleep(0) 来尝试优化线程调度,例如,避免某个线程长时间占用 CPU 而导致其他线程饥饿。
  • 实时系统(罕见): 在某些对实时性要求非常高的系统中,可能会使用 Thread.sleep(0) 来尝试更精细地控制线程调度。

代码示例:

public class ThreadSleepZeroExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Thread 1: " + i);
                if (i == 2) {
                    Thread.sleep(0); // 触发线程调度
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Thread 2: " + i);
            }
        });

        thread1.start();
        thread2.start();
    }
}

与 Thread.yield() 的区别:

实现方式:
Thread.yield() 是一个 Java API 调用,它的具体实现依赖于 JVM 和底层操作系统。
Thread.sleep(0) 在大多数操作系统上会被实现为一个非常短时间的睡眠(例如,1 毫秒或更短),或者直接触发一次线程上下文切换。
行为:
Thread.yield() 仅仅是给调度器一个提示,表示当前线程愿意让出 CPU。调度器可以忽略这个提示,继续让当前线程执行。
Thread.sleep(0) 由于涉及到了系统调用,它更可能导致实际的线程切换,因为它要求操作系统进行处理(即使时间很短)。虽然在实际上还是取决于操作系统的实现,不能百分百保证,但是会让步CPU的概率更大。

到此这篇关于深入理解Thread.sleep(0)的作用的文章就介绍到这了,更多相关Thread.sleep(0)作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • java设计模式之外观模式(Facade)

    java设计模式之外观模式(Facade)

    这篇文章主要为大家详细介绍了java设计模式之外观模式Facade的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • Java基础教程之类数据与类方法

    Java基础教程之类数据与类方法

    这篇文章主要介绍了Java基础教程之类数据与类方法,本文是对类的深入探讨,类数据指类的一些属性、参数等,类方法就是类包含的功能方法,需要的朋友可以参考下
    2014-08-08
  • 使用Java编写一个图片word互转工具

    使用Java编写一个图片word互转工具

    这篇文章主要介绍了使用Java编写一个PDF Word文件转换工具的相关资料,需要的朋友可以参考下
    2023-01-01
  • springboot扫描自定义的servlet和filter代码详解

    springboot扫描自定义的servlet和filter代码详解

    本文是一篇根据作者工作经历总结出来的关于springboot扫描自定义的servlet和filter代码详解的文章,小编觉得非常不错,这里给大家分享下,和朋友们一起学习,进步。
    2017-10-10
  • Mybatis 如何开启控制台打印sql语句

    Mybatis 如何开启控制台打印sql语句

    这篇文章主要介绍了Mybatis 如何开启控制台打印sql语句问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 介绍java中Pair(配对)

    介绍java中Pair(配对)

    这篇文章主要介绍了介绍java中Pair(配对),示例描述使用Pair类实现简单Integer到String的映射,示例中getKey方法返回key对象,getValue方法返回对应值对象,需要的朋友可以参考下
    2023-03-03
  • spring设置拦截器代码实例

    spring设置拦截器代码实例

    这篇文章主要介绍了spring设置拦截器代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 详解Spring Cloud Eureka多网卡配置总结

    详解Spring Cloud Eureka多网卡配置总结

    本篇文章主要介绍了详解Spring Cloud Eureka多网卡配置总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • 深入学习Spring Boot排查 @Transactional 引起的 NullPointerException问题

    深入学习Spring Boot排查 @Transactional 引起的 NullPointerException问题

    这篇文章主要介绍了深入学习Spring Boot排查 @Transactional 引起的 NullPointerException问题,需要的朋友可以参考下
    2018-01-01
  • Spring Security登录表单配置示例详解

    Spring Security登录表单配置示例详解

    这篇文章主要介绍了Spring Security登录表单配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论