首先我们要明确,线程中断并不会使线程立即退出,而是发送一个通知,告知目标线程你该退出了,但是后面如何处理,则完全有目标线程自行决定。
这就是和stop()不一样的地方,stop执行后线程会立即终止,这样可能会引起数据不一致的问题(所以stop()方法已经被废弃不推荐使用了)。
线程中断有三个方法
public void Thread.interrupt(); //中断线程,设置中断标志位 public void Thread.isInterrupted(); //判断是否被中断 public void Thread.interrupted(); //判断是否被中断,并清除当前中断状态
先看下面一段代码
public class InterruptThread { public static void main(String[] args) throws Exception { Thread thread = new Thread() { public void run() { while (true) { Thread.yield(); } } }; thread.start(); Thread.sleep(2000); thread.interrupt();// 设置中断标志位 } }
虽然对thread进行了中断,但是thread并没有中断处理逻辑,所以这个中断就不起作用,否则,中断就和stop没什么两样了。
再看下面的代码
package com.thread.test; public class InterruptThread { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread() { public void run() { while (true) { //Thread.currentThread().isInterrupted();检查中断标志位--检查线程是否有被中断 if (Thread.currentThread().isInterrupted()) { System.out.println("被中断了"); break; } Thread.yield(); } }; }; thread.start(); Thread.sleep(2000); thread.interrupt();//设置中断标志位 } }
isInterrupted()用于判断线程是否被中断,如果被中断则退出循环体。
请注意,代码中sleep()方法总会抛出一个InterruptedException中断异常,它不是运行时异常,因此我们必须捕获它并处理,当线程在睡眠的时候如果被中断,这个异常就会产生
请看以下代码
package com.thread.test; public class InterruptThread { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread() { public void run() { while (true) { System.out.println("未被中断"); //Thread.currentThread().isInterrupted();检查中断标志位--检查线程是否有被中断 if (Thread.currentThread().isInterrupted()) { System.out.println("被中断了"); break; } try { Thread.sleep(2000); } catch (InterruptedException e) { System.err.println("睡眠时发生了中断异常"); Thread.currentThread().interrupt();//设置中断标志位 } Thread.yield(); } }; }; thread.start(); Thread.sleep(2000); thread.interrupt();//设置中断标志位 } }
运行后输出结果为:
未被中断
睡眠时发生了中断异常
未被中断
被中断了
注意:sleep()方法由于中断而抛出异常,此时,它会清除中断标记,如果不加以处理,那么下一次循环开始时,就无法捕获这个中断,故在异常处理中,再次设置中断标记位
如果不再次设置,则会输出如下结果:
未被中断
睡眠时发生了中断异常
未被中断
未被中断
未被中断
未被中断
.......
...
.