java多线程 sleep()和wait()的区别

laxila 2012-01-05 02:38:50
加精
接触了一些多线程的东西,还是从java入手吧。

相信看这篇文章的朋友都已经知道进程和线程的区别,也都知道了为什么要使用多线程了。

这两个方法主要来源是,sleep用于线程控制,而wait用于线程间的通信,与wait配套的方法还有notify和notifyAll.

区别一:

sleep是Thread类的方法,是线程用来 控制自身流程的,比如有一个要报时的线程,每一秒中打印出一个时间,那么我就需要在print方法前面加上一个sleep让自己每隔一秒执行一次。就像个闹钟一样。

wait是Object类的方法,用来线程间的通信,这个方法会使当前拥有该对象锁的进程等待知道其他线程调用notify方法时再醒来,不过你也可以给他指定一个时间,自动醒来。这个方法主要是用走不同线程之间的调度的。

区别二 :

关于锁的释放 ,在这里假设大家已经知道了锁的概念及其意义。调用sleep方法不会释放锁(自己的感觉是sleep方法本来就是和锁没有关系的,因为他是一个线程用于管理自己的方法,不涉及线程通信)

JDK 7 中的解释:

“public static void sleep(long millis)

throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.The thread does not lose ownership of any monitors.

public final void wait() throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.“
调用wait方法会释放当前线程的锁(其实线程间的通信是靠对象来管理的,所有操作一个对象的线程是这个对象通过自己的wait方法来管理的,就好像这个对象是电视机,三个人是三个线程,那么电视机的遥控器就是这个锁,假如现在A拿着遥控器,电视机调用wait方法,那么A就交出自己的遥控器,由jVM虚拟机调度,遥控器该交给谁。)【我想到一个好玩的例子:如果A拿遥控器的期间,他可以用自己的sleep每隔十分钟调一次电视台,而在他调台休息的十分钟期间,遥控器还在他的手上~】

区别三:

使用区域

由于wait函数的特殊意义,所以他是应该放在同步语句块中的,这样才有意义 。

注意:两个方法都需要抛出异常

个人见解:有sleep和wait的第二个区别,引起了我对Java线程机制的一个疑问,目前还没有看过JDk这方面的源码(其实看了,是木有看懂),线程的同步管理,是不是由对象在调度,如果是对象在调度,那么JDK 1.5新引入的ReentrantLock机制就比synchronized关键字更值得提倡。因为他更能反映出这么一个机制来。好多人不能理解wait和sleep的区别,我认为就是因为synchronized关键字的影响。当然自己还不懂JAVA的线程具体实现,留作疑问以后有时间继续研究吧

这个小专题貌似是学长学姐们经常面面试的题目,感谢他们的经验分享~

原文地址:http://software.intel.com/zh-cn/blogs/2011/12/16/java-sleepwait/
...全文
3079 71 打赏 收藏 转发到动态 举报
写回复
用AI写文章
71 条回复
切换为时间正序
请发表友善的回复…
发表回复
爱因斯丹 2013-01-22
  • 打赏
  • 举报
回复
不错,将的例子很好,有助于理解,楼下人提问的问题也很好,学习了~! 楼主,能给推荐一个Java线程部分的博客或者书什么的都行,就单独要Java线程部分的。
tanxd39 2012-01-17
  • 打赏
  • 举报
回复
巩固了下知识,谢谢
  • 打赏
  • 举报
回复
有点明白线程了,多谢LZ
BriskJJ 2012-01-15
  • 打赏
  • 举报
回复
Thanks .
小乞丐_落尘 2012-01-13
  • 打赏
  • 举报
回复
学习了。。线程一直觉得很抽象。。没怎么深入学习。。对ConcurrentLinkedQueue) list为全局队列 。。很感兴趣。。不知道楼上的大哥。。能不能指导指导。。。谢谢。。。
  • 打赏
  • 举报
回复
相当不错的分析,对于初学者来说无疑是一个很好的例子----
life02 2012-01-11
  • 打赏
  • 举报
回复
不错,讲解到位
liuzhengkang 2012-01-10
  • 打赏
  • 举报
回复
我想知道在一个线程的run方法里,当使用sleep(1000)与wait(1000)时有什么区别?
只从运行的结果来看,是没什么区别。在此望楼主能帮小弟解释下,区别是什么,谢谢。
liuzhengkang 2012-01-10
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 guojing590 的回复:]

引用 54 楼 liuzhengkang 的回复:

我想知道在一个线程的run方法里,当使用sleep(1000)与wait(1000)时有什么区别?
只从运行的结果来看,是没什么区别。在此望楼主能帮小弟解释下,区别是什么,谢谢。

sleep(1000)只能老老实实休息1s,wait(1000)有可能在1s之内就被叫醒该干活了(没叫的话,到了1s也就自己醒了)。
对了,有一点要注……
[/Quote]
谢谢guojing590兄的解答。
如果在程序里不会在其它地方用到notify或notifyAll唤醒,而只是让线程每秒定时处理逻辑,而处理的(ConcurrentLinkedQueue) list为全局队列,即其它线程也会调用这个list来遍历对象,请问,你认为run方法里是用sleep(1000)还是wait(1000)好?
guojing590 2012-01-10
  • 打赏
  • 举报
回复
[Quote=引用 54 楼 liuzhengkang 的回复:]

我想知道在一个线程的run方法里,当使用sleep(1000)与wait(1000)时有什么区别?
只从运行的结果来看,是没什么区别。在此望楼主能帮小弟解释下,区别是什么,谢谢。
[/Quote]
sleep(1000)只能老老实实休息1s,wait(1000)有可能在1s之内就被叫醒该干活了(没叫的话,到了1s也就自己醒了)。
对了,有一点要注意,不管是sleep到了时间,还是wait被叫醒,都只是说线程有了抢占CPU的资格,不是说它一定会获得cpu,继续执行下去,因为有可能有更高优先级的线程在执行中,这就是线程的不确定性,也是线程的复杂性所在。
guojing590 2012-01-10
  • 打赏
  • 举报
回复
[Quote=引用 53 楼 yingwuluohan 的回复:]

第三点说的有点没明白啊,wait 和 notifyAll合用可以做同步功能,其作用跟 synchronized 是一样的,怎么会必须放到同步块里呢?
[/Quote]

wait 的线程可以被 同object的notify和notifyAll唤醒,所以要处于某object对象的synchonized里面才有其特殊意义
paddybear 2012-01-09
  • 打赏
  • 举报
回复
这个线程和进程的问题很多人都觉得麻烦,但是仔细想想,其实还是很容易想清楚的!
anubiszhou 2012-01-09
  • 打赏
  • 举报
回复
看见线程就头痛
yingwuluohan 2012-01-09
  • 打赏
  • 举报
回复
第三点说的有点没明白啊,wait 和 notifyAll合用可以做同步功能,其作用跟 synchronized 是一样的,怎么会必须放到同步块里呢?
major57 2012-01-09
  • 打赏
  • 举报
回复
现在做什么,吃穿问题应该不大。。衣食住行里面最难解决的是住行...[Quote=引用 45 楼 vic025 的回复:]

java写得好,不愁吃穿
[/Quote]
Defonds 2012-01-09
  • 打赏
  • 举报
回复
sleep用于线程控制,而wait用于线程间的通信
vic025 2012-01-08
  • 打赏
  • 举报
回复
java写得好,不愁吃穿
醉马不肖 2012-01-08
  • 打赏
  • 举报
回复
sleep主动释放某一时间段的CPU时间
wait 等待事件后获得CPU时间
aini3884 2012-01-08
  • 打赏
  • 举报
回复
貌似有点头绪了,谢谢楼主!
ljch4 2012-01-08
  • 打赏
  • 举报
回复
同意楼上观点
加载更多回复(24)

566

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧