我可以使用等待而不是睡眠吗? [复制]

Posted

技术标签:

【中文标题】我可以使用等待而不是睡眠吗? [复制]【英文标题】:Can I use wait instead of sleep? [duplicate] 【发布时间】:2014-05-14 12:15:15 【问题描述】:

我遇到了一个问题,发帖者试图让一个线程等待一秒钟。他们正在使用wait,但在synchronized 块之外,因此它崩溃了。

给定一个正在运行的线程,要暂停给定时间的执行,可以这样做:

Thread.sleep(1000);

这应该也可以,并且结果非常相似:

synchronized(this) 
    this.wait(1000);

使用wait 超时,线程将在 1 秒后取消暂停。

问题是这样的:如果我没有任何监控和通知问题,是否有实际理由使用一个而不是另一个?

【问题讨论】:

关于此事的有用链接:***.com/questions/1036754/… @Ivan :是的,我已经阅读了这个问题,关于这个问题的讨论是 cmets,但我并没有真正找到明确的答案。 答案是他们做不同的事情。 sleep() 会受到中断。 wait() 服从 notify()。它们不相等。 waitsleep 提供完全不同的功能。坦率地说,这似乎是另一个问题的重复。怎么不是?那里的两个最佳答案非常清楚地显示了差异。 我知道两者之间的区别。但是在某些情况下似乎能够执行相同的任务(暂停线程的执行。)在链接的问题中有讨论,但没有实际回答这个问题。 【参考方案1】:

sleep()wait() 都用于暂停当前线程,但它们是为不同的用例设计的:

sleep() 通常在您确切知道希望线程处于非活动状态多长时间时使用。在给定的超时时间后,它将自动唤醒,不受外界干扰。如果发生紧急情况,仍然有可能有人会决定提前唤醒您的线程(在这种情况下,对sleep() 的调用将以InterruptedException 结束)。例如,用户决定在线程休眠时关闭应用程序,或者类似的情况。

所以,sleep() 就像设置一个闹钟,让你在一个小时内醒来,同时你正在打瞌睡。但是有人可以早点叫醒你,说大楼着火了,最好站起来做点什么。

另一方面,wait() 旨在暂停线程,直到将来某个时间发生某些事情。你不知道需要多长时间。外面一定有人会通过调用监视器上的notify()notifyAll() 来唤醒线程(在用于调用wait() 的同一对象上)。例如,一个线程已将某项工作委托给另一个线程,并希望在工作完成之前休眠。您还可以选择限制等待时间,但线程在重新获取监视器之前不会继续执行。等待线程仍然可以像sleep()一样被中断。

所以,wait() 就像您拥有车间里唯一的螺丝刀,将它借给您的同事一段时间,然后决定打瞌睡,直到他或她完成。当您的螺丝刀再次空闲时,您要求他们叫醒您,您可以继续工作。你也可以像sleep()那样设置闹钟,但是在你拿回螺丝刀之前你将无法恢复工作。

当然,这些只是使用这些方法的常用简单方法。您可以根据其功能设计自己的使用场景。

【讨论】:

【参考方案2】:

javadoc 中的区别非常明显:

void Object.wait(): 导致当前线程等待,直到另一个线程为此对象调用 notify() 方法或 notifyAll() 方法。

void Object.wait(long timeout): 使当前线程等待,直到另一个线程为此对象调用 notify() 方法或 notifyAll() 方法,或者经过了指定的时间。

static void Thread.sleep(long millis): 使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。

否则,问题被提出并得到解释的答案 here.

【讨论】:

感谢您的回答。我知道两者之间的区别。我想知道,既然两者都可以用来达到暂停线程的目的,那么使用一个而不是另一个是有原因的。 (当没有强制使用的约束时,持有这样的监视器)。

以上是关于我可以使用等待而不是睡眠吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

有睡眠/等待吗?

在 Linux 上等待多个条件变量而没有不必要的睡眠?

Excel Power Query - 睡眠或等待命令等待 API 速率限制

使用Task.Wait而不是等待异步编程

nasm 程序集 linux 计时器或睡眠

Linux内核自旋锁