我可以用等待而不是睡觉吗?

时间:2014-04-02 22:47:45

标签: java multithreading

我遇到了一个问题,其中海报试图让一个帖子等待一秒钟。他们使用的是wait,但在synchronized块之外,因此崩溃了。

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

Thread.sleep(1000);

这也应该有效,结果非常相似:

synchronized(this) {
    this.wait(1000);
}

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

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

2 个答案:

答案 0 :(得分:5)

sleep()wait()都用于保持当前线程,但它们是针对不同的用例设计的:

当您确切知道线程处于非活动状态的时间时,通常会使用

sleep()。在给定的超时后,它将自动唤醒,不受外界干扰。如果发生紧急事件,有人可能会决定早点唤醒你的线程(在这种情况下,对sleep()的调用将以InterruptedException结束)。例如,用户决定在线程处于睡眠状态时关闭应用程序,或类似的东西。

所以,sleep()就像设置一个闹钟,在打瞌睡的同时唤醒你一小时。但是有人可以早点叫醒你说这座建筑物着火了,最好起床并做点什么。

另一方面,

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

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

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

答案 1 :(得分:1)

javadoc中的差异很明显:

  

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

     

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

     

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

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