美文网首页
001 线程中断 interrupt() | isInterru

001 线程中断 interrupt() | isInterru

作者: __destory__ | 来源:发表于2019-03-18 22:38 被阅读0次

    对于正在执行,和正在阻塞的线程,如果需要中断(或者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()效果。

    相关文章

      网友评论

          本文标题:001 线程中断 interrupt() | isInterru

          本文链接:https://www.haomeiwen.com/subject/rwvemqtx.html