首先,一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。

所以,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();
    }
}

结果:

Java 线程 interrupt 后面的内容可以执行 线程interrupt的用法_正常运行

从上面的代码来看,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)注释掉,程序运行的结果:

Java 线程 interrupt 后面的内容可以执行 线程interrupt的用法_System_02

 

 这是因为当i=3时,执行了interrupt()方法,MyClass线程被标志中断,程序继续正常运行,然后执行if(interrupted()),执行break,程序结束。

interrupted()方法是判断线程是否被中断,返回值类型是boolean型。