Thread类中有这么几个方法:
- public void interrupt()
- public static boolean interrupted()
- public boolean isInterrupted()
interrupt()
中断线程。
如果当前线程没有中断自己(这在任何情况下都是允许的),则该线程的checkAccess方法就会被调用,这可能抛出SecurityException。
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long, int)
方法,或者该类的 join()
、join(long)
、join(long, int)
、sleep(long)
或 sleep(long, int)
方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException
。
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException
。
如果该线程在一个 Selector
中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup
方法一样。
如果以前的条件都没有保存,则该线程的中断状态将被设置。
中断一个不处于活动状态的线程不需要任何作用。
抛出:
SecurityException
- 如果当前线程无法修改该线程
interrupted()
测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。
返回:
如果当前线程已经中断,则返回 true
;否则返回 false
。
isInterrupted()
测试线程是否已经中断。线程的中断状态 不受该方法的影响。
线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。
探讨interrupt
然而interrupt真的会帮你停止线程么?答案是并不会。
一段简单的代码可以如下图所示:
public class Interrupt {
public static void main(String[] args){
Thread thread1 = new Thread(){
public void run(){
try {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time<200){
System.out.println("I am alive");
}
System.out.println("A1");
} catch (Exception e) {
// TODO: handle exception
System.out.println("B1");
}
}
};
thread1.start();
thread1.interrupt();
System.out.println(thread1.getName()+" "+thread1.isInterrupted());
}
代码还是会输出I am alive
也就是说启动的线程并没有因为调用interrupt方法而终止,可是从isInterrupted方法返回的结果来看,线程是已经中断了的;
根本原因是因为没有深刻理解,JAVA API对这个方法的描述。我们再回头看一下:
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long, int)
方法,或者该类的 join()
、join(long)
、join(long, int)
、sleep(long)
或 sleep(long, int)
方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException
。
该方法实际上只是设置了一个中断状态,当该线程由于上述原因而受阻时,这个中断状态就起作用了。
也许我们当设置了一个interrupt状态以后,应该采用如下的响应机制,来进一步完成理论上应该达到的interrupt效果。
下面这段话引用自http://redisliu.blog.sohu.com/131647795.html
当外部线程对某线程调用了thread.interrupt()方法后,java语言的处理机制如下:
如果该线程处在可中断状态下,(调用了xx.wait(),或者Selector.select(),Thread.sleep()等特定会发生阻塞的api),那么该线程会立即被唤醒,同时会受到一个InterruptedException,同时,如果是阻塞在io上,对应的资源会被关闭。如果该线程接下来不执行“Thread.interrupted()方法(不是interrupt),那么该线程处理任何io资源的时候,都会导致这些资源关闭。当然,解决的办法就是调用一下interrupted(),不过这里需要程序员自行根据代码的逻辑来设定,根据自己的需求确认是否可以直接忽略该中断,还是应该马上退出。
如果该线程处在不可中断状态下,就是没有调用上述api,那么java只是设置一下该线程的interrupt状态,其他事情都不会发生,如果该线程之后会调用行数阻塞API,那到时候线程会马会上跳出,并抛出InterruptedException,接下来的事情就跟第一种状况一致了。如果不会调用阻塞API,那么这个线程就会一直执行下去。除非你就是要实现这样的线程,一般高性能的代码中肯定会有wait(),yield()之类出让cpu的函数,不会发生后者的情况。