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

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

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

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


当前回答

wait()是Object类的一个方法。 sleep()是Thread类的一个方法。 Sleep()允许线程进入睡眠状态x毫秒。 当线程进入睡眠状态时,它不会释放锁。 Wait()允许线程释放锁并进入挂起状态。 当notify()或notifAll()方法被激活时,该线程将处于活动状态 为同一个对象调用。

其他回答

一个等待线程可以被另一个调用正在被等待的监视器上的notify线程“唤醒”,而一个睡眠线程则不能。另外,一个wait(和notify)必须发生在monitor对象上同步的块中,而sleep则不会:

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

此时,当前正在执行的线程等待并释放监视器。另一个线程可以

synchronized (mon) { mon.notify(); }

(在同一个mon对象上)和第一个线程(假设它是在监视器上等待的唯一线程)将被唤醒。

如果有多个线程在监视器上等待,您也可以调用notifyAll—这将唤醒所有线程。但是,只有一个线程能够获取监视器(记住,等待是在同步块中)并继续执行—其他线程将被阻塞,直到它们获得监视器的锁。

另一点是你在对象本身调用wait(即你在对象的监视器上调用wait),而你在线程上调用sleep。

还有一点是,你可以从wait中得到虚假的唤醒(例如,正在等待的线程没有明显的原因就恢复了)。你应该总是等待在某些条件下旋转,如下所示:

synchronized {
    while (!condition) { mon.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来访问这些方法。

我希望这对你有所帮助。

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

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

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

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

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

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

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

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

来源:http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/

wait()方法。

1)调用wait()方法的线程释放它持有的锁。

2)在其他线程调用同一锁上的notify()或notifyAll()方法后,线程重新获得锁。

3) wait()方法必须在同步块内调用。

4) wait()方法总是在对象上被调用。

5)等待中的线程可以通过调用notify()或notifyAll()方法被其他线程唤醒。

6)要调用wait()方法,线程必须有对象锁。

睡眠()方法

1)调用sleep()方法的线程不释放它持有的锁。

2) sleep()方法可以在同步块内部或外部调用。

3) sleep()方法总是在线程上调用。

4)睡眠线程不能被其他线程唤醒。如果这样做,线程将抛出InterruptedException。

5)调用sleep()方法时,线程不需要有对象锁。