关于Java thread的Interrupt, isInterrupt, interrupted【转】
在《Java网络编程》上看到一个例子, 说是用thread.interrupt()去关闭在等待的线程。不太明白,于是去查了一下Java的API。
有兴趣的同行们可以先看看API的内容,再看以下总结:
1. thread.isInterrupt()和Thread.interrupted()都返回当前线程interrupt的状态
- thread.isInterrupt()是非静态函数,作用目标是“线程实例”,一般用法如下,
- TestInterrupt t = new TestInterrupt();
- t.start();
- System.out.println(t.isInterrupt());
- 而Thread.interrupted()是静态函数,作用目标是“当前线程”
- System.out.println(Thread.interrupted());
并且它会把当前线程的interrupt状态“复位”,假设当前线程的isInterrupt状态为true,它会返回true,但过后isInterrupt的状态会复位为false。之后调用(Thread)t.isInterrupt或Thread.interrupted都会返回false
2. interrupt()被调用后有几个可能,下面挑几种常见的归类一下:
线程阻塞的情况下:
- 如果线程在调用
Object
类的wait()
、wait(long)
或wait(long, int)
方法,或者该类的join()
、join(long)
、join(long, int)
、sleep(long)
或sleep(long, int)
方法过程中受阻,则其isInterrupt状态将被清除,设成false, 它还将收到一个InterruptedException.
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- try{
- Thread.sleep(1000);
- } catch (InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
如上所示,如果线程运行到Thread.sleep(1000)时,被其他线调用了该线程的interrupt()的方法,它将会进入catch的段落里面,然后再运行while (!Thread.currentThread().isInterrupted()) 时退出run, 线程被销毁。
- 如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的isInterrupt状态将被设置成true, 并且该线程将收到一个
ClosedByInterruptException
。
线程正常运行的情况下:
- 该线程不受影响,继续运行,但该线程的isInterrupt状态将被设置成true
- public void run() {
- while (!Thread.currentThread().isInterrupted()) {
- try{
- //A: 无阻塞的代码.......
- ......
- //B: 被调用interrupt.......
- ......
- //C: 无阻塞的代码.......
- } catch (InterruptedException ie){
- ie.printStackTrace();
- }
- }
- }
如上所示, 当线程正常运行时,在运行到B点时被调用了interrupt(), 此时该线程将继续正常运行,但isInterrupt的状态会被设为true,当做完 A,B,C的代码时,再进入while (!Thread.currentThread().isInterrupted()) 时,该线程被销毁。假如while的检查条件改为(true),该线程不会受影响,将会一直运行下去。