内联Java IDE提示声明,“在循环中调用Thread.sleep会导致性能问题。”我在文档的其他地方找不到解释。这句话。
为什么呢?怎么样?还有什么其他方法可以延迟线程的执行?
答案 0 :(得分:34)
循环中的Thread.sleep
本身并不是性能问题,但通常暗示你做错了。
while(! goodToGoOnNow()) {
Thread.sleep(1000);
}
仅当您要暂停线程一段时间时才使用Thread.sleep
。如果你想等待一定的条件,请不要使用它。
对于这种情况,您应该使用wait/notify
代替或并发utils包中的一些构造。
仅当等待当前JVM外部的条件时才应使用Thread.sleep
进行轮询(例如,等待另一个进程写入文件)。
答案 1 :(得分:6)
这取决于等待是否依赖于完成工作的另一个线程,在这种情况下,您应该使用Java 1.6中引入的guarded blocks或high level concurrency classes。我最近不得不修复一些使用Thread睡眠而不是保护块的CircularByteBuffer
代码。使用前面的方法,无法确保正确的并发性。如果你只是希望线程像游戏一样睡觉,那么在核心游戏循环中暂停执行一段时间,以便线程有足够的执行时间,Thread.sleep(..)
完全正常。
答案 2 :(得分:5)
这取决于你为什么要睡觉以及你经常跑的频率。
我可以想到几种可能适用于不同情况的替代方案:
答案 3 :(得分:3)
http://www.jsresources.org/faq_performance.html
1.6。我可以从Thread.sleep()得到什么精度?
短暂睡眠的基本问题是对睡眠的调用完成当前的调度时间片。只有在所有其他线程/进程完成后,调用才能返回。
对于Sun JDK,据报道Thread.sleep(1)在Windows上非常精确。对于Linux,它取决于内核的定时器中断。如果使用HZ = 1000(alpha上的默认值)编译内核,则报告精度良好。对于HZ = 100(x86上的默认值),它通常会休眠20毫秒。
使用Thread.sleep(millis,nanos)不会改善结果。在Sun JDK中,纳秒值仅舍入到最接近的毫秒。 (马蒂亚斯)
答案 4 :(得分:2)
为什么呢?这是因为上下文切换(OS CPU调度的一部分)
如何?调用Thread.sleep(t)使当前线程从正在运行的队列移动到等待队列。在't'到达之后,当前线程从等待队列移动到就绪队列,然后由CPU选择并运行它需要一些时间。
解决方案:调用Thread.sleep(t * 10);而不是在10次迭代的循环内调用Thread.Sleep(t)......
答案 5 :(得分:1)
在等待异步进程返回结果之前,我遇到过这个问题。
Thread.sleep是多线程场景中的问题。它往往睡过头了。这是因为它在内部重新排列其优先级并产生其他长时间运行的进程(线程)。
一种新方法是在Java 5中使用ScheduledExecutorService接口或ScheduledThreadPoolExecutor。
参考:http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html
答案 6 :(得分:1)
这可能不是问题,取决于。
在我的情况下,我使用Thread.sleep()等待几秒钟,然后再尝试重新连接到外部进程。这个重新连接逻辑有一个while循环,直到达到最大尝试次数。所以在我的例子中,Thread.sleep()纯粹是出于计时目的而不是多线程之间的协调,它完全没问题。
您可以为IDE配置如何处理此警告。
答案 7 :(得分:0)
我建议查看CountDownLatch类。在线有很多简单的例子。回到我刚开始多线程编程的时候,他们只是替换“睡觉时循环”的票。