首先,复写父类的方法不能比父类抛出更多的异常。
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对象的监视锁。 |