Thread.sleep(0)的作用

简介: 在源码中经常能看到sleep(0)的操作,今天来总结下sleep(0)的作用到底是啥

Java相关文章


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)的作用一是主动让出cpu调度提升系统调度性能,二是使系统进入safepoint标记gc。





相关文章
|
3天前
sleep()和wait()的区别
(1)wait()是Object的方法,sleep()是Thread类的方法 (2)wait()会释放锁,sleep()不会释放锁 (3)wait()要在同步方法或者同步代码块中执行,sleep()没有限制 (4)wait()要调用notify()或notifyall()唤醒,sleep()自动唤醒
13 5
|
4月前
|
Java C# Python
线程等待(Thread Sleep)
线程等待(Thread Sleep)
|
5月前
|
Java 编译器 UED
Thread.sleep()总结
Thread.sleep()总结
|
6月前
|
监控 算法 Unix
Thread.sleep(0) 到底有什么用
Thread.sleep(0) 到底有什么用
54 1
sleep () 和 wait () 的区别
sleep () 和 wait () 的区别
89 0
|
监控
Sleep()和wait()方法的区别
Sleep()和wait()方法的区别
136 0
|
Java 程序员
sleep 和 wait 的区别
Java 中,线程的 "sleep" 和 "wait" 方法区别
129 0
|
消息中间件 安全 Java
|
调度 C++
Thread.sleep(0) vs Thread.sleep(1) vs Thread.yield() vs Object.wait()
Thread.sleep(0) vs Thread.sleep(1) vs Thread.yield() vs Object.wait()
|
Java 调度 C++
你真的了解Thread.sleep(0)吗?以及Thread.sleep(1) vs Thread.sleep(0)
你真的了解Thread.sleep(0)吗?以及Thread.sleep(1) vs Thread.sleep(0)