线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
从oracle文档页面的wait()方法的对象:
public final void wait()
导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。换句话说,这个方法的行为就像简单地执行调用wait(0)一样。 当前线程必须拥有该对象的监视器。线程释放该监视器的所有权并等待,直到另一个线程通知等待该对象监视器的线程被唤醒 可能会出现中断和虚假唤醒 此方法只能由该对象的监视器的所有者的线程调用
这个方法抛出
IllegalMonitorStateException -如果当前线程不是对象的监视器的所有者。 InterruptedException——如果任何线程在当前线程等待通知之前或期间中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。
从oracle文档页关于Thread类的sleep()方法:
public static void sleep(long millis)
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,这取决于系统计时器和调度器的精度和准确性。 线程不会失去任何监视器的所有权。
这个方法抛出:
IllegalArgumentException -如果millis的值为负 InterruptedException -如果任何线程中断了当前线程。抛出此异常时,当前线程的中断状态将被清除。
其他关键区别:
Wait()是一个非静态方法(实例方法),不同于静态方法sleep()(类方法)。
其他回答
等待和睡眠的方法非常不同:
睡眠无法“唤醒”, 而wait在等待期间有一种“唤醒”的方式,由另一个线程调用notify或notifyAll。
仔细想想,这些名字在这方面令人困惑;然而,sleep是一个标准名称,而wait就像Win API中的WaitForSingleObject或WaitForMultipleObjects。
应该从同步块调用:wait()方法总是从同步块调用,即wait()方法需要在调用它的对象之前锁定对象监视器。但是sleep()方法可以从外部同步块调用,即sleep()方法不需要任何对象监视器。
IllegalMonitorStateException:如果wait()方法被调用而没有获得对象锁,则IllegalMonitorStateException在运行时抛出,但sleep()方法从不抛出此类异常。
属于哪个类:wait()方法属于java.lang.Object类,sleep()方法属于java.lang.Thread类。
在对象或线程上调用:wait()方法在对象上调用,而sleep()方法在线程上调用,而不是在对象上。
线程状态:当在对象上调用wait()方法时,持有对象监视器的线程从运行状态变为等待状态,只有在该对象上调用notify()或notifyAll()方法时才能返回到可运行状态。然后线程调度程序将线程从可运行状态调度到运行状态。 当sleep()在线程上被调用时,它会从运行状态转到等待状态,并在休眠时间结束时返回到可运行状态。
从同步块调用时:当wait()方法被调用时,线程离开对象锁。但是sleep()方法在从同步块或方法线程调用时不会留下对象锁。
更多参考资料
实际上,所有这些都在Java文档中有清楚的描述(但我是在阅读答案后才意识到这一点)。
http://docs.oracle.com/javase/8/docs/api/index.html:
wait() -当前线程必须拥有该对象的监视器。线程释放 该监视器的所有权,并等待直到另一个线程通知 在此对象的监视器上等待的线程可以通过 调用notify方法或notifyAll方法。那么线程 等待,直到它可以重新获得监视器的所有权并恢复执行。
sleep() -根据系统计时器和调度器的精度和准确性,使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数。线程不会失去任何监视器的所有权。
这是一个非常简单的问题,因为这两种方法有完全不同的用途。
主要的区别是等待释放锁或监视器,而sleep在等待时不释放任何锁或监视器。Wait用于线程间通信,而sleep用于执行时引入暂停。
这只是一个清晰而基本的解释,如果你想了解更多,请继续阅读。
在wait()方法的情况下,线程进入等待状态,它不会自动返回,直到我们调用notify()方法(或notifyAll()如果你有多个线程处于等待状态,你想唤醒所有这些线程)。您需要同步或对象锁或类锁来访问wait()或notify()或notifyAll()方法。还有一件事,wait()方法用于线程间通信,因为如果一个线程处于等待状态,您将需要另一个线程来唤醒该线程。
但是对于sleep(),这是一个用于将进程保持几秒钟或您想要的时间的方法。因为您不需要调用任何notify()或notifyAll()方法来取回线程。或者你不需要任何其他线程来回调那个线程。比如,如果你想让某些事情在几秒钟后发生,比如在游戏中,在用户轮到自己之后,你想让用户等待直到电脑开始运行,那么你可以使用sleep()方法。
还有一个在面试中经常被问到的更重要的区别:sleep()属于Thread类,wait()属于Object类。
这些就是sleep()和wait()之间的所有区别。
这两个方法之间有一个相似之处:它们都是checked语句,所以你需要try catch或throws来访问这些方法。
我希望这对你有所帮助。
方法wait(1000)使当前线程休眠一秒。 如果线程接收到notify()或notifyAll()方法调用,那么线程的睡眠时间可能小于1秒。 调用sleep(1000)会导致当前线程休眠1秒。 此外,睡眠线程不持有锁任何资源。但是等待线程可以。