001 线程中断 interrupt() | isInterru

2019-03-18  本文已影响0人  __destory__

对于正在执行,和正在阻塞的线程,如果需要中断(或者stop),可以采用以下几种方式,

  1. 对要停止的线程,使用stop()方法,
  2. 对要停止的线程,使用interrupt()方法

对于,stop()方法已经废弃,因为涉及到资源未回收等安全问题,

阻塞线程的中断

使得线程阻塞的方法,sleep(), wait()等,对于这些阻塞方法,会强制使用try catch包围,捕获, InterruptedException。

try {
    Thread.sleep(100); // 休眠100ms
} catch (InterruptedException ie) {  
}

因此,当我们阻塞的线程调用interrupt()方法后,会对线程设置中断标记,阻塞的地方,会识别中断标记,并抛出InterruptedException,后,清除中断标记 !!!。此时此刻,调用isInterrupted()方法,会得到false。

try {
    Thread.sleep(900); // 休眠900ms,多等一会,让main线程中断他
} catch (InterruptedException ie) {  
    System.out.println(isInterrupted());
    System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException.");  
}

//main函数
Thread t1 = new Demo1("t1");  // 新建“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");  

t1.start();  // 启动“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");  

// 主线程休眠300ms,然后主线程给t1发“中断”指令。
Thread.sleep(300);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");

// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");

//输出结果
t1 (NEW) is new.
t1 (RUNNABLE) is started.
t1 (TIMED_WAITING) is interrupted.  //sleep()中断时线程状态
false//被中断后,异常捕获,清空中断状态,变成false
t1 (RUNNABLE) catch InterruptedException.
t1 (TERMINATED) is interrupted now.

运行中线程的中断

运行中的线程,即没有被阻塞,也是通过interrupt()方法对线程进行中断,此时,线程被的中断标记被设置为true,通过isInterrupted()可以获得true,通常如法做法,

通过中断标志

@Override
public void run() {
    int i=0;
    while(!isInterrupted()) {
        ++i;
        System.out.println(Thread.currentThread().getName()+" "+i+" "+isInterrupted());
    }
    System.out.println(Thread.currentThread().getName()+" "+i+" "+isInterrupted());
}

//main函数
Thread t1 = new Demo1("t1");  // 新建“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");  

t1.start();  // 启动“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");  

// 主线程短暂休息。
Thread.sleep(1);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");

// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");

//输出结果
t1 (NEW) is new.
t1 (RUNNABLE) is started.
t1 1 false
t1 2 false
....
t1 31 false
t1 (RUNNABLE) is interrupted.
t1 31 true //发现了true
t1 (TERMINATED) is interrupted now.

通过标记变量

通过其他变量,来进行判断,如果设置为false,则跳出循环

private volatile boolean flag= true;
protected void stopTask() {
    flag = false;
}

@Override
public void run() {
    while (flag) {
        // 执行任务...
    }
}

线程的中断通常设置方法

一个线程运行过程中,有阻塞的时候,也有运行的时候,阻塞的时候中断,需要记住中断标记在异常捕获后会清楚 。代码如下

@Override
public void run() {
    try {
        // 1. isInterrupted()保证,只要中断标记为true就终止线程。
        while (!isInterrupted()) {
            // 执行任务...
        }
    } catch (InterruptedException ie) {  
        // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
    }
}

当然,可以通过设置变量来替换掉!isInterrupted()效果。

上一篇 下一篇

猜你喜欢

热点阅读