A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 游兴钟 中级黑马   /  2012-5-24 03:18  /  2263 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在论坛中看关于sleep和wait区别时,多次看到:sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。
实在无法理解。

4 个回复

倒序浏览
sleep和wait都是使线程暂时停止执行的方法
,但它们有很大的不同,sleep是线程类Thread 的方法,
它是使当前线程暂时睡眠,可以放在任何位置。
而wait是Object类的方法,它是使当前线程暂时放弃对象的使用权进行等待,
必须放在同步方法或同步块里。
Sleep使用的时候,线程并不会放弃对象的使用权,即不会释放对象锁,所以在同步方法或同步块中使用sleep,一个线程访问时,其他的线程也是无法访问的。
而wait是会释放对象锁的,就是当前线程放弃对象的使用权,让其他的线程可以访问。
线程执行wait方法时,需要另一个线程调用notify进行唤醒。
而sleep只是暂时休眠一定时间,时间到了之后,自动恢复运行。


评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。
Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }

4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

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


区别一:

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


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

区别二 :

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

而wait会释放锁~

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
java线程中的sleep和wait有一个相同的作用是停止当前线程任务运行,但有区别之处,
(1)sleep方法属于Thread类中的方法,表示让一个线程进入睡眠状态,等待一定的时间后,自动醒来进入到可运行状态,而不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法后,并不会释放它所有的对象锁,也不会影响其他线程对象的运行。但在睡眠的过程中有可能被其他对象调用它的interrupt()产生InterruptException异常,如果程序不捕获该异常,线程就会异常终止 ,进入Terminated(程序停止)状态,如果程序捕获了该异常,则程序就会继续执行catch块及后边的代码。

sleep()方法是一个静态方法,它只对当前对象有效,通过o.sleep()让o对象进入sleep,它只会使当前线程睡眠而不是o线程。

(2)wait属于Object的成员方法,一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该线程,如果线程拥有某些对象的同步锁,则在调用了wait()后,该线程就会释放它的所有同步资源 ,而不限于这个被调用了wait()方法的对象。wait()方法也会在wait的过程中有可能被其他对象调用interrupt()方法而产生InterruptedException,处理方式与sleep方法相同。

notify()是释放对象的wait()方法而阻塞线程,这个释放是随机的,也就是不一定要释放哪个线程。
notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。但是这一对方法却必须在 synchronized方法或块中调用,因为只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。

这里简述一下interrupt(),interrupt是中断。一个线程被调用interrupt()后,会影响到sleep、wait方法,同时方法内部会不断检查中断状态的值,若发现线程的状态被置为已中断,sleep、wait方法便会抛出InterruptedException异常。被中断的线程则将控制权交给了catch语句。interrupted方法是查询是否有“中断状态”这一标志 ,通常情况下这一标志未被设置,一旦调用了interrupt()方法,interrupt()就设置了这个标志 ,则所有当前正在阻塞的方法(由于wait、sleep方法引发的阻塞)都会立刻完成“跳出
阻塞状态、抛出InterruptedException异常,清除中断状态标志”这三个任务。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马