并发编程<二>线程中断和线程中断标志

来源:互联网 发布:童声配音软件 编辑:程序博客网 时间:2024/04/25 22:19

转发请声明出处:http://blog.csdn.net/qq_24692041/article/details/78455131


线程中断,interrupt方法

 先看代码和输出结果

 子线程代码:

package com.example;/** * Created by PICO-USER on 2017/11/6. */public class ThreadA extends Thread {     @Override    public void run() {        super.run();        try{            System.out.println("in ThreadA - about to sleep for 20 seconds :"+isInterrupted());            Thread.sleep(20000);            System.out.println("in ThreadA - wake up");        }catch(InterruptedException e){            System.out.println("in ThreadA - interrupted while sleeping");            System.out.println("in ThreadA - interrupt status of threadA :"+isInterrupted());            //处理完中断异常后,返回到run()方法人口,            //如果没有return,线程不会实际被中断,它会继续打印下面的信息          //  return;        }        System.out.println("in ThreadA - leaving normally");    }}

主线程代码:

package com.example;public class MyClass {    public static void main(String[] args0) throws InterruptedException {        ThreadA threadA = new ThreadA();        threadA.start();        //主线程休眠2秒,从而确保刚才启动的线程有机会执行一段时间        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("in main() - interrupting other thread");        //中断线程t        threadA.interrupt();        System.out.println("in main() - interrupt status of threadA :"+threadA.isInterrupted());        System.out.println("in main() - leaving");    }}
输出结果:


代码和结果分析:

主程序中先启动了线程A,此时线程A的run方法开始执行,打印完“in run() - about to sleep for 20 seconds”之后A进入休眠状态,休眠20秒。此时主线程是在并发执行的,主线程休眠2秒,2秒过后主线程休眠结束,调用interrupt方法中断A线程,并且主线程main方法执行完毕,所以主线程消亡。此时A线程本应该还在休眠状态,但由于interrupt方法被调用,直接让A线程结束了休眠状态抛出了中断异常,然后继续执行try,catch后面的代码,run方法走完之后消亡。这里注意:如果在catch块中return,那后面的代码将不会继续执行,因为return代表run方法执行结束,A线程就直接消亡了。

重点:从上面的代码可以看出interrupt方法的调用只是在目标线程中设置了中断标志为true,代表该线程已经被中断,并不会直接终止该线程注意看isInterrupt方法打印出来的结果,在A线程开始执行run方法的时候打印的是false,然后中断A线程的一瞬间我们在主线程打印了A线程的中断状态是true,最后在A线程的catch块中打印出来的却是false,说明interrupt方法的调用的时候的确是设置了中断标志,并且没有直接终止线程的执行。

当线程遇到阻塞,比如调用sleep,wait,join方法的时候,就会抛出中断异常,并且重置中断标志。所以上面catch方法中的isInterrupt方法返回的是false。

最后说一点,其实上面我们在主线程打印A线程中断标志的时候有取巧的嫌疑,只是打印的位置哈,interrupt设置中断标志的结论肯定是没错的。因为在主线程中打印A的中断标志的时候,有可能A的异常已经被抛出,并且重置了中断标志,那样的结果就会是false。


方法判断线程中断

线程中断判断方法有两个,一个是interrupted()方法,该方法是静态方法,该方法是中断当前线程并且该方法会将中断标志重置,另一个方法就是上面用到的isInterrupted()方法,这个方法是非静态方法,作用于对象,返回的是目标线程的中断标志,本身并不会重置中断标志,需要线程阻塞,比如调用sleep,wait,join方法导致阻塞的时候,将中断标志重置。下面看看两个示例代码:

package com.example;/** * Created by PICO-USER on 2017/11/6. */public class ThreadB extends Thread {    @Override    public void run() {        super.run();        System.out.print("ThreadB isInterrupted :"+isInterrupted()+"\n");        System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"\n");        interrupt();        System.out.print("ThreadB isInterrupted :"+isInterrupted()+"\n");        System.out.print("ThreadB isInterrupted :"+isInterrupted()+"\n");        System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"\n");        System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"\n");    }}

package com.example;public class MyClass {    public static void main(String[] args0) throws InterruptedException {        ThreadB threadB = new ThreadB();        threadB.start();        System.out.print("main :" + Thread.currentThread().isInterrupted() + "\n");    }}
运行结果:


很清楚的看到调用interrupt方法之后连续打印的两次isInterrupted的返回值都是true,然而第一次调用interrupted方法的返回值是true,但是第二次调用的时候就已经被重置返回false了。

阅读全文
1 0
原创粉丝点击