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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马-王建雨 中级黑马   /  2012-4-15 13:18  /  2326 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 啷个里个郞 于 2012-5-8 13:11 编辑

为什么wait方法抛出的异常只能try,不能throw呢?

4 个回复

正序浏览
首先,复写父类的方法不能比父类抛出更多的异常。
wait方法是final的,只能被子类继承,不能被子类重写。
wait方法会抛出InterruException  。一个线程在调用interr()后,自己不会抛出异常,所以你看到interrupt()并没有抛出这个异常,所以说如果线程a在执行while(条件)x++,你调用a.interrupt();后线程会正常执行下去。
  但是,如果一个线程被调用了interrupt()后,它的状态是已中断的。这个状态对于正在执行wait的线程,却改变了线程的运行结果。
   对于wait中等待notify/notifyAll唤醒的线程,其实这个线程已经“暂停”执行,因为它正在某一对象的休息室中,这时如果它的状态被改变,那么他就会抛出异常。这个InterruptedException异常不是线程抛出的,而是wait方法,也就是对象的wait方法内部会不断检查在此对象上休息的线程的状态,如果发现哪个线程的状态被置为已中断,则会抛出InterruptedException,意思是这个线程不能再等待了,其意义就等同于唤醒它了。
   这里唯一的区别是,被notify/notifyAll唤醒的线程会继续执行wait下面的语句,而在wait中被中断的线程则将控制权交给了catch语句。一些正常的逻辑要被放到catch语句中来运行。但有时这是唯一的手段,比如一个线程a在某一个对象b的wait中等待唤醒,其它线程必须获得对象b的监视锁才能调用b.notify()[All],否则你就无法唤醒线程a,但在任何线程中可以无条件的调用a.interrupt();来达到这个目的。只是唤醒后的逻辑你要放在catch中,当然同notify/notifyAll一样,继续执行a线程的条件还是要等拿到b对象的监视锁。

评分

参与人数 1技术分 +1 收起 理由
岳民喜 + 1

查看全部评分

回复 使用道具 举报
子类继承父类,若父类中没有异常则子类不能抛出异常,
只有try,而且如果子类能跑出异常,子类抛出的异常只能是父类异常的子集。

如果你的wait()父类没有抛异常,这里的wait也不能抛
回复 使用道具 举报
try只能获取程序运行时引发的异常,而throw语句可以引发明确的异常,程序到了throw语句这后就立即停止,不会执行后面的程序,
回复 使用道具 举报
这要看在什么地方wait的,如果在其他函数中wait,然后在run()方法中调用了此函数,那wait方法可以在那个函数中抛,然后在run()方法中try,其实wait()不可以抛是因为wait()在run()方法中,其父类没有异常抛出,所以不能将run()方法中的异常抛出。一个子类继承父类,若父类中没有异常则子类不能抛出异常,只能try,子类抛出的异常只能是父类异常的子集。

评分

参与人数 1技术分 +1 收起 理由
岳民喜 + 1

查看全部评分

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