Java 在哪些情况下,Thread.sleep()是暂停线程的最佳方法?

Java 在哪些情况下,Thread.sleep()是暂停线程的最佳方法?,java,multithreading,Java,Multithreading,Thread.sleep()对我来说似乎是一个非常无用的概念,因为我看到它工作的唯一方式是在以下场景中 public void someFunction() { //thread does something Thread.sleep(50000); //now other threads do something } 问题是,对我来说,这只是自找麻烦。我的意思是,这可能太长,在这种情况下,最多可能会出现性能问题,可能太长,其他线程可能会等待结果,在这

Thread.sleep()
对我来说似乎是一个非常无用的概念,因为我看到它工作的唯一方式是在以下场景中

 public void someFunction()
 {
      //thread does something
      Thread.sleep(50000);
      //now other threads do something
 }
问题是,对我来说,这只是自找麻烦。我的意思是,这可能太长,在这种情况下,最多可能会出现性能问题,可能太长,其他线程可能会等待结果,在这种情况下,情况可能会变得非常严重

我的意思是,还有其他方法,比如使用synchronized和wait,它们看起来效率更高


因此,我的问题是,在任何情况下,使用线程睡眠都是最佳选择吗?

尽管事件驱动模型在很多情况下是“等待”某个操作发生的最佳方式,但有时您需要故意等待一小段时间,然后再执行某个操作。 这种情况的一种常见情况是在某些时间段之间采样/轮询数据(来自文件、网络等)。在这种情况下,您只想在时间间隔之间“刷新”数据


例如,如果您有一个通过网络向web服务发出请求的应用程序,您可能希望定期执行此任务,大部分时间处于“睡眠”状态,但在一段时间后执行服务请求任务,一次又一次地重复此行为。

考虑一个服务启动两个不同的线程,执行两个相互连接的不同操作,其中一个线程失败,一个异常被捕获(网络问题,远程主机不响应),您希望您的服务在尽可能短的时间内启动并运行。最好是等待一段时间,然后重新运行失败的线程。您不知道远程主机何时启动,必须测试连接。在这种情况下,最好的解决方案是等待一段时间,然后重新运行线程,而不是无休止地重新运行失败的线程(CPU负载)

如果没有sleep()方法,就不可能编写java.util.Timer,或者至少需要滥用wait()方法,并在其周围编写大量额外代码以防止虚假唤醒。

线程.sleep(long)和对象.wait(long)都阻止当前线程。但是,
wait
可能会更早返回(虚假唤醒),请参阅javadoc。因此,对于
wait
,我们需要实现额外的逻辑,以确保经过指定的时间量。因此,如果您只是想暂停,请使用
Thread.sleep

每当您想放慢速度时,都可以使用
Thread.sleep
。在某些情况下,您无法同步,例如在通过网络、数据库等与外部系统通信的情况下

示例场景:

  • 错误恢复-当您的系统依赖于某个报告临时错误的外部实体时。您与无法控制的外部系统进行通信,该系统表示存在与您的请求无关的临时问题。执行
    线程。睡眠
    并重试。如果您没有
    睡眠
    ,则会出现错误泛滥。这是集成中间件中非常常见的模式
  • 超时-您等待某事发生,但不超过10秒。你不能接受更长的等待时间,而想退出
  • 节流-有人告诉你,你做某事的频率不能超过10秒一次

请记住,等待有多种方式,不一定要调用
线程。sleep

如果需求规范要求五秒钟的等待,可能在某些过程控制线程代码的几个函数的深处,可能只有在某些条件下,才需要睡眠(5000)call是一个很好的解决方案,原因如下:

  • 它不需要将简单的内联代码重写为复杂代码 状态机,以便能够使用异步计时器

  • 它不需要运行其他计时器或池线程来实现超时

  • 它是一个单行程序,不需要等待对象被构造等

  • Sleep()在我使用过的所有多任务操作系统上都以几乎相同的形式提供

Sleep()因以下原因而受到负面影响:

  • 它“浪费一根线”。在许多系统中,例如,当线程无论如何都将在那里并且将在应用程序的生命周期中运行时,谁在乎呢

  • 它经常被错误地用于线程间通信轮询循环,因此增加CPU浪费和延迟确实是站不住脚的

  • 它通常不能被打断,以便“干净、快速” 关闭线程。同样,在许多系统中,池线程或应用生命周期线程是否因进程终止而被粗暴地停止并不重要,所以为什么还要费心尝试呢

合理使用示例:

void StartFeedstockDelivery{
  if (airbankPressure()<MIN_PRESSURE){
    startCompressor();
    sleep(10000);  // wait for pressure to build up
  openFeedValve();
};
作废StartFeedstockDelivery{

if(airbankPressure())如果您正在轮询非阻塞服务,那么Thread.sleep是有用的。另外,我使用Thread.sleep在杀死ssh线程之前等待一段时间。如果您想执行定期任务,通常可以使用sleep。并发库使用LockSupport.park(),这是一个更高级的线程。sleep().关于sleep()的用途有很多很好的答案。以下是它不适用的内容:它不适用于同步。同步错误是不确定的:有时它们会叮咬你,有时它们会休眠。有时,添加sleep()在正确的地方打电话似乎可以让bug消失,但不要被愚弄。真正发生的是,你只是让bug变得不那么活跃,也许会造成这样一种情况,当它最终再次出现时,它会在一个重要客户的站点而不是在你的测试台上这样做。@PeterLawrey,
LockSupport.park
不会这样做现在
InterruptedException
,它只是被
线程唤醒