线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
线程中的wait()和sleep()有什么区别?
我是否理解wait()-ing线程仍然处于运行模式并使用CPU周期,但sleep()-ing不消耗任何CPU周期正确?
为什么我们同时使用wait()和sleep()?
它们的实现在较低级别上有什么不同?
当前回答
sleep是Thread的一个方法,wait是Object的一个方法,所以wait/notify是Java中同步共享数据的一种技术(使用monitor),而sleep是线程暂停自身的一种简单方法。
其他回答
这些方法用于不同的事情。
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是起点…
sleep是Thread的一个方法,wait是Object的一个方法,所以wait/notify是Java中同步共享数据的一种技术(使用monitor),而sleep是线程暂停自身的一种简单方法。
在研究了wait和sleep之后,我总结了一些不同的关键注意事项,首先看一下使用wait()和sleep()的示例:
例1:使用wait()和sleep():
synchronized(HandObject) {
while(isHandFree() == false) {
/* Hand is still busy on happy coding or something else, please wait */
HandObject.wait();
}
}
/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
/* Beer is still coming, not available, Hand still hold glass to get beer,
don't release hand to perform other task */
Thread.sleep(5000);
}
/* Enjoy my beer now ^^ */
drinkBeers();
/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
HandObject.notifyAll();
}
让我们明确一些关键的注意事项:
呼吁: wait():调用当前持有handdobject对象的线程 sleep():在线程上调用执行任务获取啤酒(是类方法,因此影响当前运行的线程) 同步: wait():当同步多线程访问同一对象(HandObject)时(当多个线程之间需要通信时(线程执行编码,线程执行获取啤酒)访问同一对象(HandObject) sleep():当等待状态继续执行时(等待啤酒可用) 持有锁: wait():释放锁,让其他对象有机会执行(HandObject是空闲的,你可以做其他工作) sleep():保持锁至少t次(或直到中断)(我的工作仍然没有完成,我继续持有锁,等待一些条件继续) 唤醒条件: wait():直到调用notify(), notifyAll()从对象 Sleep():直到至少超时或调用中断 最后一点是当estani表示:
通常使用sleep()进行时间同步,使用wait()进行时间同步 multi-thread-synchronization。
如果我说错了,请指正。
我发现这篇文章很有帮助。它将Thread.sleep(), Thread.yield()和Object.wait()之间的区别放在人类术语中。引用:
这一切最终都会传到操作系统的调度程序 将时间片分发给进程和线程。 sleep(n)表示“我已经用完了我的时间片,请不要给我 再来一次,至少n毫秒。”操作系统甚至不会尝试这样做 调度睡眠线程,直到请求的时间过去。 yield()表示“我已经完成了我的时间片,但我仍然有工作要做 做的。”操作系统可以立即给线程另一个时间片, 或者给CPU的其他线程或进程生成线程 就这么放弃了。 wait()表示“我完成了我的时间片。别再给我了 时间片,直到有人调用notify()。”与sleep()一样,操作系统不会这样做 甚至尝试调度您的任务,除非有人调用notify()(或其中之一) 还有其他一些醒来的场景)。 线程在执行时也会丢失剩余的时间片 阻塞IO和其他一些情况下。如果线程工作 在整个时间片中,操作系统强制控制大致为 如果已经调用yield(),则其他进程可以运行。 你很少需要yield(),但是如果你有一个计算量很大的应用程序 逻辑任务边界,插入yield()可以改善系统 响应性(以时间为代价——上下文切换,甚至只是 到操作系统并返回,不是免费的)。衡量和测试你的目标 在乎,一如既往。
你是正确的- Sleep()导致线程“睡眠”,CPU将离开并处理其他线程(也称为上下文切换),而我认为Wait保持CPU处理当前线程。
我们两者都有,因为尽管让其他人在你不使用CPU时使用它似乎是明智的,但实际上上下文切换是有开销的——取决于睡眠的时长,在CPU周期中切换线程可能比简单地让你的线程在几毫秒内什么都不做要昂贵得多。
还要注意,睡眠会强制进行上下文切换。
此外——通常情况下控制上下文切换是不可能的——在等待期间,操作系统可能(并且会有更长的等待)选择处理其他线程。