【发布时间】:2010-10-18 03:52:51
【问题描述】:
内联 Java IDE 提示状态,“在循环中调用 Thread.sleep 会导致性能问题。”我在文档的其他地方找不到任何说明。这个声明。
为什么?如何?还有什么其他方法可以延迟线程的执行?
【问题讨论】:
-
也许您可以更改问题以澄清它实际上是来自某些 IDE 的警告......例如“'Invoking ...'可能意味着哪个性能问题?”
标签: java multithreading
内联 Java IDE 提示状态,“在循环中调用 Thread.sleep 会导致性能问题。”我在文档的其他地方找不到任何说明。这个声明。
为什么?如何?还有什么其他方法可以延迟线程的执行?
【问题讨论】:
标签: java multithreading
循环中的Thread.sleep 本身并不是性能问题,而是通常暗示你做错了什么。
while(! goodToGoOnNow()) {
Thread.sleep(1000);
}
仅当您想将线程挂起一段时间时才使用Thread.sleep。如果您想等待某个条件,请不要使用它。
对于这种情况,您应该改用wait/notify 或并发工具包中的一些构造。
只有在等待当前 JVM 外部的条件时才应使用 Thread.sleep 轮询(例如等待另一个进程写入文件)。
【讨论】:
这取决于等待是否依赖于另一个线程完成工作,在这种情况下你应该使用guarded blocks,或者Java 1.6中引入的high level concurrency classes。我最近不得不修复一些使用线程休眠而不是受保护块的CircularByteBuffer 代码。使用以前的方法,无法确保正确的并发性。如果你只是想让线程像游戏一样休眠,在核心游戏循环中暂停执行一段时间,以便线程有良好的执行时间,Thread.sleep(..) 非常好。
【讨论】:
这取决于你为什么让它进入睡眠状态以及你运行它的频率。
我能想到几种适用于不同情况的替代方案:
【讨论】:
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 中,纳秒值只是四舍五入到最接近的毫秒。 (马蒂亚斯)
【讨论】:
为什么?那是因为上下文切换(操作系统 CPU 调度的一部分)
怎么样?调用 Thread.sleep(t) 使当前线程从运行队列移动到等待队列。在时间 't' 到达后,当前线程从等待队列移动到就绪队列,然后需要一些时间被 CPU 挑选并运行。
解决方法:调用 Thread.sleep(t*10);而不是在 10 次迭代的循环内调用 Thread.Sleep(t) ...
【讨论】:
我之前在等待异步进程返回结果时遇到过这个问题。
Thread.sleep 是多线程场景的问题。它往往会睡过头。这是因为它在内部重新排列其优先级并让给其他长时间运行的进程(线程)。
一种新方法是使用 ScheduledExecutorService 接口或 java 5 中引入的 ScheduledThreadPoolExecutor。
参考:http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html
【讨论】:
这可能不是问题,这取决于。
在我的例子中,我使用 Thread.sleep() 等待几秒钟,然后再次尝试重新连接到外部进程。我有一个用于此重新连接逻辑的 while 循环,直到它达到最大尝试次数。因此,就我而言, Thread.sleep() 纯粹是出于计时目的,而不是在多线程之间进行协调,这很好。
您可以配置您的 IDE 以如何处理此警告。
【讨论】:
我建议研究 CountDownLatch 类。网上有很多琐碎的例子。当我刚开始多线程编程时,它们只是替换“sleeping while loop”的门票。
【讨论】: