线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
一个等待线程可以被另一个调用正在被等待的监视器上的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(); }
}
其他回答
这些方法用于不同的事情。
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep(n)可以被中断,但是Object.wait()必须被通知。 可以指定等待的最大时间:Object.wait(5000),这样就可以使用wait,呃,睡眠,但这样你就不得不使用锁了。
这两种方法都不会在休眠/等待时使用cpu。
这些方法是使用本地代码实现的,使用类似的结构,但方式不同。
自己寻找:本机方法的源代码是否可用?文件/src/share/vm/prims/jvm.cpp是起点…
方法wait(1000)使当前线程休眠一秒。 如果线程接收到notify()或notifyAll()方法调用,那么线程的睡眠时间可能小于1秒。 调用sleep(1000)会导致当前线程休眠1秒。 此外,睡眠线程不持有锁任何资源。但是等待线程可以。
sleep是Thread的一个方法,wait是Object的一个方法,所以wait/notify是Java中同步共享数据的一种技术(使用monitor),而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来访问这些方法。
我希望这对你有所帮助。
实际上,所有这些都在Java文档中有清楚的描述(但我是在阅读答案后才意识到这一点)。
http://docs.oracle.com/javase/8/docs/api/index.html:
wait() -当前线程必须拥有该对象的监视器。线程释放 该监视器的所有权,并等待直到另一个线程通知 在此对象的监视器上等待的线程可以通过 调用notify方法或notifyAll方法。那么线程 等待,直到它可以重新获得监视器的所有权并恢复执行。
sleep() -根据系统计时器和调度器的精度和准确性,使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数。线程不会失去任何监视器的所有权。