如果一个方法后面有“throws InterruptedException”(即会抛出InterruptedException异常的方法),表示这个方法内(或是这个方法中所调用的方法内),可能会抛出InterruptedException异常。在多线程程序设计中,这通常告诉我们两点:
  1. 这是“需要时间”的方法
  2. 这是“可以取消”的方法
即,如果一个方法后面有“thorws InterruptedException”表示这个方法可能会花点时间,但是可以取消。 Java中会抛出InterruptException异常的有下面三个方法:
  1. java.lang.Object类(及其子类)实例的wait方法
  2. java.lang.Object类(及其子类)实例的sleep方法
  3. java.lang.Thread类(及其子类)实例的join方法
根据上面的两点,首先,这三个方法都是需要花点时间的方法,这个很好理解。其次,他么都可以被取消,具体怎么取消,下面分别说明。 取消wait 可以调用interrupt方法(这个方法是java.lang.Thread类(及其子类)实例的方法,某个线程都可以在任何时候调用其他线程的interrupt方法)来取消wait方法的等待。即不用再等待notify/notifyAll方法的“通知”了。当对某个wait的线程调用interrupt方法的时候,这个线程会从wait set中出来,先重新获得锁定,再抛出InterruptedException。注意,在获得锁定前,是不会抛出InterruptedException异常的。 为了加深理解,这里对比一下notify/notifyAll方法和interrupt方法。首先,notify/notifyAll方法是java.lang.Object类(及其子类)实例的方法,而interrupt方法是java.lang.Thread类(及其子类)实例的方法。其次,notify/notifyAll方法调用时需要获得锁定,而interrupt方法不用,如前所述,interrupt方法可以在任何时候被调用。最后,被notify/notifyAll方法唤醒的线程是(重新获得锁定后)继续执行wait方法之后的方法,而被interrupt方法唤醒的线程则满足前面所的第二条“可以被取消”,即让被唤醒的线程(重新获得锁定后)在wait方法上抛出InterruptedException。 取消sleep 当sleep中的线程被调用interrupt方法时,会马上(不用想取消wait一样,还要获得锁定)放弃sleep状态,并抛出InterruptedException异常。 取消join 当线程以join方法等待其他线程结束时,可以被调用interrupt方法来马上取消等待其他线程结束。 下面是关于java内部是怎么实现取消上面三个方法的等待的。在线程内部,有一个标志位表示线程的中断状态。有两个方法可以设置这个状态,interrupt方法和interrupted方法,interrupted方法属于java.lang.Thread类(及其子类)的静态方法,用来返回当前线程的中断状态,并清除这个状态。调用interrupt方法将设置此标志位(表示让被调用线程处于中断状态),调用interrupted方法返回值是当前线程是否被中断,并取消此标志位(表示让当前线程处于非中断状态)。在实现细节上,会抛出InterruptedException异常的sleep,wait和join方法在内部不断的检测这个中断状态,如果发现被设置了,则抛出InterruptedException异常。java.lang.Thread类(及其子类)实例还有一个isInterrupted方法来检测这个标志位,如果被设置了返回true,否则返回false。还需要进一步补充的是:interrupt方法和interrupted方法的区别。可以对任意的一个线程调用interrupt方法,但是只能对当前的线程(即正在运行的线程)调用interrupted方法(此方法是静态方法),所以,在程序中无法清除其他线程的中断状态了。 参考: 《Java多线程设计模式》,中国铁道出版社,2005,结城浩
文章来源:http://localhost/wp2/?p=99