首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。
所以,Thread.stop,Thread.suspend,Thread.resume都已经被废弃了。
而Thread.interrupt的作用其实也不是中断线程,而是"通知线程应该中断了",具体到底中断还是继续运行,应该由被通知的线程自己处理。
具体来说,当对一个线程,调用interrupt()时,
1.如果线程处于被阻塞状态(例如处于sleep,wait,join等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。仅此而已。
2.如果线程处于正常活动状态,那么会将该线程的中断标志设置为true,仅此而已。被设置中断标志的线程将继续正常运行,不受影响。
interrupt()并不能真正的中断线程,需要被调用的线程自己进行配合才行。也就是说,一个线程如果有被中断的需求,那么我们通常可以这样处理:
a.在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志位就自行停止线程。
b.在调用阻塞方法是正确处理InterruptedException异常。(例如,catch异常后就结束线程。)
举个例子,对interrupt和interrupted进行说明,代码如下:
public class MyClass extends Thread { public void run(){ try { for (int i = 1; i < 5; i++) { System.out.print(i + " "); if (i > 2) interrupt(); sleep(2000); if (interrupted()) break; } } catch (InterruptedException e) { System.out.println(" caught"); } } public static void main(String[] args) { MyClass my = new MyClass(); my.start(); } }
结果:
从上面的代码来看,main线程中执行my.start()开启线程MyClass,执行run()方法。执行过程: i=1-->控制台打印输出1-->sleep(2),睡2秒-->i=2-->控制台打印输出2-->sleep(2),2秒-->i=3-->控制台打印输出3-->执行interrupt(),MyClass线程被标志中断,但线程继续运行-->sleep(2),睡2秒,程序阻塞-->抛出InterruptedException异常-->控制台打印输出" caught"。程序之执行sleep后直接抛出异常,理由就是上面提到过的(红色1)。
如果将上面代码中的sleep(2)注释掉,程序运行的结果:
这是因为当i=3时,执行了interrupt()方法,MyClass线程被标志中断,程序继续正常运行,然后执行if(interrupted()),执行break,程序结束。
interrupted()方法是判断线程是否被中断,返回值类型是boolean型。