Thread.sleep() 的 Java 性能问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3956512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:07:55  来源:igfitidea点击:

Java performance issue with Thread.sleep()

javamultithreading

提问by fcw

Inline Java IDE hint states, "Invoking Thread.sleep in loop can cause performance problems." I can find no elucidation elsewhere in the docs re. this statement.

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

Why? How? What other method might there be to delay execution of a thread?

为什么?如何?还有什么其他方法可以延迟线程的执行?

回答by Thilo

It is not that Thread.sleepin a loop itself is a performance problem, but it is usually a hint that you are doing something wrong.

并不是说Thread.sleep循环本身就是性能问题,而是通常暗示您做错了什么。

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

Use Thread.sleeponly if you want to suspend your thread for a certain amount of time. Do not use it if you want to wait for a certain condition.

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

For this situation, you should use wait/notifyinstead or some of the constructs in the concurrency utils packages.

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

Polling with Thread.sleepshould be used only when waiting for conditions external to the current JVM (for example waiting until another process has written a file).

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

回答by Chris Dennett

It depends on whether the wait is dependent on another thread completing work, in which case you should use guarded blocks, or high level concurrency classesintroduced in Java 1.6. I recently had to fix some CircularByteBuffercode that used Thread sleeps instead of guarded blocks. With the previous method, there was no way to ensure proper concurrency. If you just want the thread to sleep as a game might, in the core game loop to pause execution for a certain amount of time so that over threads have good period in which to execute, Thread.sleep(..)is perfectly fine.

这取决于等待是否依赖于另一个线程完成工作,在这种情况下,您应该使用受保护的块,或者Java 1.6 中引入的高级并发类。我最近不得不修复一些CircularByteBuffer使用线程睡眠而不是受保护块的代码。使用之前的方法,无法确保适当的并发性。如果您只想让线程像游戏一样休眠,那么在核心游戏循环中暂停执行一段时间,以便线程有良好的执行时间,这Thread.sleep(..)完全没问题。

回答by Brad Mace

It depends on why you're putting it to sleep and how often you run it.

这取决于您将其置于睡眠状态的原因以及运行它的频率。

I can think of several alternatives that could apply in different situations:

我可以想到几种适用于不同情况的替代方案:

  • Let the thread die and start a new one later (creating threads can be expensive too)
  • Use Thread.join() to wait for another thread to die
  • Use Thread.yield() to allow another thread to run
  • Let the thread run but set it to a lower priority
  • Use wait() and notify()
  • 让线程死掉然后再开始一个新线程(创建线程也可能很昂贵)
  • 使用 Thread.join() 等待另一个线程死亡
  • 使用 Thread.yield() 允许另一个线程运行
  • 让线程运行但将其设置为较低的优先级
  • 使用 wait() 和 notify()

回答by Adrian

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

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

1.6. What precision can I expect from Thread.sleep()?

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

The fundamental problem with short sleeps is that a call to sleep finishes the current scheduling time slice. Only after all other threads/process finished, the call can return.

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

For the Sun JDK, Thread.sleep(1) is reported to be quite precise on Windows. For Linux, it depends on the timer interrupt of the kernel. If the kernel is compiled with HZ=1000 (the default on alpha), the precision is reported to be good. For HZ=100 (the default on x86) it typically sleeps for 20 ms.

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

Using Thread.sleep(millis, nanos) doesn't improve the results. In the Sun JDK, the nanosecond value is just rounded to the nearest millisecond. (Matthias)

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

回答by test

why? that is because of context switching (part of the OS CPU scheduling)

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

How? calling Thread.sleep(t) makes the current thread to be moved from the running queue to the waiting queue. After the time 't' reached the the current thread get moved from the waiting queue to the ready queue and then it takes some time to be picked by the CPU and be running.

如何?调用 Thread.sleep(t) 使当前线程从运行队列移动到等待队列。在时间“t”到达后,当前线程从等待队列移动到就绪队列,然后它需要一些时间被 CPU 选择并运行。

Solution: call Thread.sleep(t*10); instead of calling Thread.Sleep(t) inside loop of 10 iterations ...

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

回答by Rulix Batistil

I have face this problem before when waiting for asynchronous process to return a result.

我之前在等待异步进程返回结果时遇到过这个问题。

Thread.sleep is a problem on multi thread scenario. It tends to oversleep. This is because internally it rearrange its priority and yields to other long running processes (thread).

Thread.sleep 是多线程场景中的一个问题。它倾向于睡过头。这是因为它在内部重新安排其优先级并让步给其他长时间运行的进程(线程)。

A new approach is using ScheduledExecutorService interface or the ScheduledThreadPoolExecutor introduce in java 5.

一种新方法是使用 ScheduledExecutorService 接口或 Java 5 中引入的 ScheduledThreadPoolExecutor。

Reference: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html

参考:http: //download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html

回答by Yu Chen

It might NOT be a problem, it depends.

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

In my case, I use Thread.sleep() to wait for a couple of seconds before another reconnect attempt to an external process. I have a while loop for this reconnect logic till it reaches the max # of attemps. So in my case, Thread.sleep() is purely for timing purpose and not coordinating among multithreads, it's perfectly fine.

就我而言,我使用 Thread.sleep() 等待几秒钟,然后再尝试重新连接到外部进程。对于这个重新连接逻辑,我有一个 while 循环,直到它达到最大尝试次数。所以就我而言, Thread.sleep() 纯粹是为了计时目的,而不是在多线程之间进行协调,这完全没问题。

You can configure you IDE in how this warning should be handled.

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

回答by Ivan

I suggest looking into the CountDownLatch class. There are quite a few trivial examples out there online. Back when I just started multithreaded programming they were just the ticket for replacing a "sleeping while loop".

我建议查看 CountDownLatch 类。网上有很多简单的例子。回到我刚开始多线程编程时,它们只是替换“sleeping while loop”的门票。