线程中的wait()和sleep()有什么区别?

我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?

为什么我们同时使用wait()和sleep()?

它们的实现在较低级别上有什么不同?


当前回答

让我们假设你正在听到歌曲。

只要当前歌曲正在运行,下一首歌就不会播放,即由下一首歌调用Sleep()

如果你完成了这首歌,它会停止,直到你选择播放按钮(notify())它才会播放,即由当前歌曲调用的wait()。

在这两种情况下,歌曲都进入等待状态。

其他回答

这是一个非常简单的问题,因为这两种方法有完全不同的用途。

主要的区别是等待释放锁或监视器,而sleep在等待时不释放任何锁或监视器。Wait用于线程间通信,而sleep用于执行时引入暂停。

这只是一个清晰而基本的解释,如果你想了解更多,请继续阅读。

在wait()方法的情况下,线程进入等待状态,它不会自动返回,直到我们调用notify()方法(或notifyAll()如果你有多个线程处于等待状态,你想唤醒所有这些线程)。您需要同步或对象锁或类锁来访问wait()或notify()或notifyAll()方法。还有一件事,wait()方法用于线程间通信,因为如果一个线程处于等待状态,您将需要另一个线程来唤醒该线程。

但是对于sleep(),这是一个用于将进程保持几秒钟或您想要的时间的方法。因为您不需要调用任何notify()或notifyAll()方法来取回线程。或者你不需要任何其他线程来回调那个线程。比如,如果你想让某些事情在几秒钟后发生,比如在游戏中,在用户轮到自己之后,你想让用户等待直到电脑开始运行,那么你可以使用sleep()方法。

还有一个在面试中经常被问到的更重要的区别:sleep()属于Thread类,wait()属于Object类。

这些就是sleep()和wait()之间的所有区别。

这两个方法之间有一个相似之处:它们都是checked语句,所以你需要try catch或throws来访问这些方法。

我希望这对你有所帮助。

我发现这篇文章很有帮助。它将Thread.sleep(), Thread.yield()和Object.wait()之间的区别放在人类术语中。引用:

这一切最终都会传到操作系统的调度程序 将时间片分发给进程和线程。 sleep(n)表示“我已经用完了我的时间片,请不要给我 再来一次,至少n毫秒。”操作系统甚至不会尝试这样做 调度睡眠线程,直到请求的时间过去。 yield()表示“我已经完成了我的时间片,但我仍然有工作要做 做的。”操作系统可以立即给线程另一个时间片, 或者给CPU的其他线程或进程生成线程 就这么放弃了。 wait()表示“我完成了我的时间片。别再给我了 时间片,直到有人调用notify()。”与sleep()一样,操作系统不会这样做 甚至尝试调度您的任务,除非有人调用notify()(或其中之一) 还有其他一些醒来的场景)。 线程在执行时也会丢失剩余的时间片 阻塞IO和其他一些情况下。如果线程工作 在整个时间片中,操作系统强制控制大致为 如果已经调用yield(),则其他进程可以运行。 你很少需要yield(),但是如果你有一个计算量很大的应用程序 逻辑任务边界,插入yield()可以改善系统 响应性(以时间为代价——上下文切换,甚至只是 到操作系统并返回,不是免费的)。衡量和测试你的目标 在乎,一如既往。

Sleep()方法导致当前线程在指定的时间内从运行状态转移到阻塞状态。如果当前线程拥有任何对象的锁,那么它会一直持有它,这意味着其他线程不能在该类对象中执行任何同步方法。

Wait()方法会导致当前线程在指定的时间内进入阻塞状态或直到notify,但在这种情况下,线程会释放对象的锁(这意味着其他线程可以执行调用对象的任何同步方法)。

你是正确的- Sleep()导致线程“睡眠”,CPU将离开并处理其他线程(也称为上下文切换),而我认为Wait保持CPU处理当前线程。

我们两者都有,因为尽管让其他人在你不使用CPU时使用它似乎是明智的,但实际上上下文切换是有开销的——取决于睡眠的时长,在CPU周期中切换线程可能比简单地让你的线程在几毫秒内什么都不做要昂贵得多。

还要注意,睡眠会强制进行上下文切换。

此外——通常情况下控制上下文切换是不可能的——在等待期间,操作系统可能(并且会有更长的等待)选择处理其他线程。

实际上,所有这些都在Java文档中有清楚的描述(但我是在阅读答案后才意识到这一点)。

http://docs.oracle.com/javase/8/docs/api/index.html:

wait() -当前线程必须拥有该对象的监视器。线程释放 该监视器的所有权,并等待直到另一个线程通知 在此对象的监视器上等待的线程可以通过 调用notify方法或notifyAll方法。那么线程 等待,直到它可以重新获得监视器的所有权并恢复执行。

sleep() -根据系统计时器和调度器的精度和准确性,使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数。线程不会失去任何监视器的所有权。