线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
这里有很多答案,但我找不到任何一个提到的语义区别。
这与线程本身无关;这两种方法都是必需的,因为它们支持非常不同的用例。
sleep()让线程像以前一样进入睡眠状态,它只是打包上下文并在预定义的时间内停止执行。因此,为了在到期时间之前唤醒它,您需要知道Thread引用。这在多线程环境中并不常见。它主要用于时间同步(例如,在3.5秒内醒来)和/或硬编码的公平性(只睡一会儿,让其他线程工作)。
相反,wait()是一种线程(或消息)同步机制,它允许您通知没有存储引用(也没有关心)的线程。您可以将其视为一个发布-订阅模式(wait == subscribe and notify() == publish)。基本上,使用notify()你是在发送一条消息(甚至可能根本没有收到,通常情况下你并不关心)。
总而言之,通常使用sleep()进行时间同步,使用wait()进行多线程同步。
它们可以在底层操作系统中以同样的方式实现,也可以完全不实现(因为以前版本的Java没有真正的多线程;可能一些小的虚拟机也不这样做)。别忘了Java是在VM上运行的,所以你的代码会根据所运行的VM/OS/HW的不同而转换成不同的东西。
其他回答
从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()是在同步方法中给出的 而sleep()是在非同步方法中给出的,因为wait()方法会释放对象上的锁,而sleep()或yield()会释放对象上的锁。
简单地说,wait是等待,直到其他线程调用你,而sleep是在指定的一段时间内“不执行下一个语句”。
此外,sleep是Thread类中的静态方法,它在线程上操作,而wait()是Object类中的静态方法,在对象上调用。
还有一点,当你在某个对象上调用wait时,线程同步该对象,然后等待。:)
在这里,我列出了wait()和sleep()方法之间的一些重要区别。 PS:也可以点击链接查看库代码(内部工作,只是为了更好地理解而玩一下)。
wait ()
Wait()方法释放锁。 wait()是Object类的方法。 wait()是非静态方法——public final void wait()会抛出InterruptedException{//…} wait()应该由notify()或notifyAll()方法通知。 Wait()方法需要从循环中调用,以处理假警报。 wait()方法必须从同步上下文(即同步方法或块)调用,否则将抛出IllegalMonitorStateException
睡眠()
Sleep()方法不释放锁。 sleep()是java.lang.Thread类的方法。 sleep()是静态方法——public static void sleep(long millis, int nanos)会抛出InterruptedException{//…} 在指定的时间量之后,sleep()将完成。 Sleep()最好不要从循环中调用(即。参见下面的代码)。 Sleep()可以从任何地方调用。没有具体的要求。
参考:等待和睡眠的区别
调用等待和睡眠方法的代码片段
synchronized(monitor){
while(condition == true){
monitor.wait() //releases monitor lock
}
Thread.sleep(100); //puts current thread on 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()方法时,线程不需要有对象锁。