如何中断正在执行的线程

众所周知,Thread类本身就有个stop方法来停止线程。但是stop()方法已经被弃用,why?

原因是stop()方法太过于暴力,会强行把执行一半的线程终止。这样会就不会保证线程的资源正确释放,通常是没有给与线程完成资源释放工作的机会,因此会导致程序工作在不确定的状态下。

使用interrept 停止线程:

interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程。这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态。 更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。

线 程A在执行sleep,wait,join时,线程B调用线程A的interrupt方法,的确这一个时候A会有 InterruptedException 异常抛出来。但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。 如果线程A正在执行一些指定的操作时如值,for,while,if,调用方法等,不会去检查中断状态,则线程A不会抛出 InterruptedException,而会一直执行着自己的操作。

测试代码:(中断阻塞线程与中断非阻塞线程)

PS:只是调用interrupt()方法设置标志位,不在子线程中对标志位处理,interrupt()方法起不到中断的效果

public class main {
    public static void main(String[] args){
        ThreadA t1 = new ThreadA();
        Thread thread =new Thread(t1);
        thread.start();
        try {
            //让启动的线程执行两秒后,发出中断信号
            Thread.sleep(2000l);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

    }

    static class ThreadA implements Runnable{

        @Override
        public void run() {
            //isInretrupted()方法获取中断标志位,不会设置中断标志位
            while(!Thread.currentThread().isInterrupted()){
                //=======================测试中断阻塞线程==============================
//                try {
//                    System.out.println("线程"+Thread.currentThread().getName()+"的中断标志位为"+Thread.currentThread().isInterrupted());
//                    Thread.sleep(3000l);
//                } catch (InterruptedException e) {
                //当线程处于sleep状态时,main()方法调用interrupt()方法发出中断信号,sleep()方法检测到中断标志位更新抛出异常,取消标志位
//                    System.out.println("线程"+Thread.currentThread().getName()+"发生异常的中断标志位为"+Thread.currentThread().isInterrupted());
//                    e.printStackTrace();
                //如果在sleep状态时,catch到异常,如果想使线程中断,必须在异常里面再次设置标志位
//                    Thread.currentThread().interrupt();
//                    System.out.println("线程"+Thread.currentThread().getName()+"发生异常再次中断标志位为"+Thread.currentThread().isInterrupted());
//                }
                //=========================测试中断非阻塞线程===================================
                    System.out.println("非阻塞线程正在执行");

            }
            System.out.println("非阻塞线程已经终止");
        }
    }
}
参考:https://blog.csdn.net/zhangliangzi/article/details/52485319

你可能感兴趣的:(多线程)