2010-10-18 78 views
21

内联Java IDE提示状态“在循环中调用Thread.sleep可能导致性能问题。”我在文档的其他地方找不到任何说明。这个说法。Thread.sleep()的Java性能问题

为什么?怎么样?还有什么其他方法可以延迟执行线程?

+0

也许你可以改变这个问题来澄清它实际上是来自某个IDE的警告......比如“哪个性能问题可以用'调用...'来表示?” – ShiDoiSi 2010-10-18 13:34:12

回答

6

这取决于等待是否依赖于另一个线程完成工作,在这种情况下,您应该使用在Java 1.6中引入的或high level concurrency classes。我最近不得不修复一些CircularByteBuffer代码,它使用线程休眠而不是保护块。使用先前的方法,无法确保正确的并发性。如果你只是希望线程能够像游戏一样进入休眠状态,那么在核心游戏循环中暂停执行一定的时间,以便线程有很好的执行周期,Thread.sleep(..)非常好。

33

循环中不是Thread.sleep本身就是一个性能问题,但它通常暗示您做错了什么。

while(! goodToGoOnNow()) { 
    Thread.sleep(1000); 
} 

仅当您想暂停您的线程一段时间时才使用Thread.sleep。如果你想等待一定的条件,不要使用它。

对于这种情况,您应该使用wait/notify来替代或使用并发utils包中的某些构造。

只有在等待当前JVM外部的条件(例如等待另一个进程写入文件)时才应使用Thread.sleep轮询。

+0

感谢您的回复。该线程通过TCP与外部设备进行通信,等待它开始运行: – fcw 2010-10-18 07:02:27

+0

该协议是,您正在运行?没有睡觉.....你在跑步吗?不,睡觉...你在跑吗?是。继续....所以没有问题。谢谢! – fcw 2010-10-18 07:04:50

+0

不要忘记InterruptedException。 – 2015-08-11 19:34:42

5

这取决于你为什么要睡觉,以及你运行它的频率。

我能想到的,可以适用于不同情况的几个备选方案:

  • 让线程芯片,后来开始一个新的(创建线程可能过于昂贵)
  • 使用的Thread.join()等待另一个线程死亡
  • 使用Thread.yield()来允许另一个线程来运行
  • 让线程运行,但将其设置为较低的优先级
  • Use wait() and notify()
0

我建议看看CountDownLatch类。网上有很多简单的例子。当我刚刚开始多线程编程时,他们只是替换“睡眠while循环”的票据。

2

为什么?那是因为上下文切换(部分OS CPU调度)

如何?调用Thread.sleep(t)使当前线程从正在运行的队列移动到等待队列。时间't'到达后,当前线程从等待队列移动到就绪队列,然后CPU需要一段时间才能选取并运行。

解决方法:调用Thread.sleep(t * 10);而不是调用10次循环内的Thread.Sleep(t)...

3

http://www.jsresources.org/faq_performance.html

1.6。 Thread.sleep()可以期望什么精度?

短暂休眠的根本问题是睡眠呼叫完成当前调度时间片。只有在所有其他线程/进程完成后,该呼叫才能返回。

对于Sun JDK,在Windows上报告Thread.sleep(1)非常精确。对于Linux,它取决于内核的定时器中断。如果内核编译时HZ = 1000(默认为alpha),则报告的精度很好。对于HZ = 100(x86上的默认值),它通常会休眠20 ms。

使用Thread.sleep(millis,nanos)不会改进结果。在Sun JDK中,纳秒值只是四舍五入到最接近的毫秒。 (Matthias)

1

这可能不是问题,它取决于。

在我的情况下,我使用Thread.sleep()等待几秒钟,然后重新尝试连接到外部进程。我有一个这个重新连接逻辑的while循环,直到达到最大尝试次数。所以在我的情况下,Thread.sleep()纯粹是为了时间目的,而不是在多线程之间进行协调,这非常好。

您可以配置您的IDE如何处理此警告。