Java多线程(七)——线程中断

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xcymorningsun/article/details/88017179

目录

一、引言

二、stop与interrupt

三、非阻塞线程被interrupt

四、阻塞线程被interrupt

五、总结


一、引言

线程中断在开始没有特别重视,多线程往后学习才发现线程中断也是件比较有技巧的事情,停止线程不像break语句中那样简单,什么时候停止,停止后代码是否执行,如何捕捉线程异常都是我们需要学习的内容。

正常情况下我们停止线程有三种方法

  1. 使用退出标志,使线程正常退出,也就是当run方法完成后才停止;

  2. 就是我们上面所说的使用stop方法强行终止线程,是过期作废的方法,这种方法可以排除不用;

  3. 使用interrupt方法终止线程。

第一种比较常见这里建议使用第三种也重点讲第三种,以及为什么在第二种和第三种选择了第二种。

二、stop与interrupt

stop方法比较强势,直接把所用的停止,但是因为威力太强大所以我们不建议使用,举个例子

public class Testinterrupt {
    public  static  void main(String [] args) {

        Thread thread= new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName()+"start");

                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    System.out.println("线程中止");//线程终止后报异常
                }
                System.out.println(Thread.currentThread().getName()+"end");

            }
        });
        System.out.println(Thread.currentThread().getName()+"start");

        thread.start();
        try {
            Thread.sleep(2000);
            //thread.interrupt();//中止线程报异常,如果使用stop(),子线程与后面的代码不会执行
            thread.stop();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"end");



    }
}

输出结果:(结果是子线程在stop后面的全部没有输出,连个异常都没抛,但是使用interrupt方法后面的代码可以继续执行)

mainstart
Thread-0start
mainend

三、非阻塞线程被interrupt

先上个例子

public class Test3 {


    public  static  void  main(String []args)
    {

         final Thread thread1= new Thread(new Runnable() {
            public void run() {

                    while (true)
                    {
                        System.out.println(Thread.currentThread().getName()+"is running");


                        if(Thread.currentThread().isInterrupted())
                        {
                            System.out.println(Thread.currentThread().getName()+"interrupt,即将退出");
                            //throw new InterruptedException();
                        }
                        //Thread.sleep(1000);
                        //countDownLatch.countDown();

                    }

            }
        });
         thread1.start();
        new Thread(new Runnable() {
            public void run() {
/*                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                thread1.interrupt();

            }
        }).start();

    }


}

输出结果:

Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0interrupt,即将退出
Thread-0is running
Thread-0interrupt,即将退出
Thread-0is running
Thread-0interrupt,即将退出

打印出来了即将推出字眼说明子线程已经被interrupt掉,但是我们发现子线程没有停止,那中断有个毛线用处,要他有何用?

表着急,线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。

下面进行手动抛出异常

public class Test3 {


    public  static  void  main(String []args)
    {



         final Thread thread1= new Thread(new Runnable() {
            public void run() {
                try {
                    while (true)
                    {
                        System.out.println(Thread.currentThread().getName()+"is running");


                        if(Thread.currentThread().isInterrupted())
                        {
                            System.out.println(Thread.currentThread().getName()+"interrupt,即将退出");
                            throw new InterruptedException();
                        }
                        //countDownLatch.countDown();

                    }
                } catch (InterruptedException e) {
                    System.out.println("进入ExceptionInterrupt2 类中run方法的catch了!");
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"is ending");


            }
        });
         thread1.start();
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                thread1.interrupt();

            }
        }).start();

    }


}

输出结果

Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0is running
Thread-0interrupt,即将退出
进入ExceptionInterrupt2 类中run方法的catch了!
java.lang.InterruptedException
	at com.question.Test3$1.run(Test3.java:31)
	at java.lang.Thread.run(Thread.java:748)
Thread-0is ending

这次程序就在我们捕捉到异常的位置停止了

四、阻塞线程被interrupt

下面再写一个阻塞子线程被interrupt的例子

public class Test3 {


    public  static  void  main(String []args)
    {
        
         final Thread thread1= new Thread(new Runnable() {
            public void run() {
                //for (int i=0;i<10;i++)
                try {
                    while (true)
                    {
                        System.out.println(Thread.currentThread().getName()+"is running");


                        if(Thread.currentThread().isInterrupted())
                        {
                            System.out.println(Thread.currentThread().getName()+"interrupt,即将退出");
                            throw new InterruptedException();
                        }
                        Thread.sleep(1000);

                    }
                } catch (InterruptedException e) {
                    System.out.println("进入ExceptionInterrupt2 类中run方法的catch了!");
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"is ending");


            }
        });
         thread1.start();
        new Thread(new Runnable() {
            public void run() {

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //System.out.println("到达5个,结束线程");
                thread1.interrupt();
                //System.out.println("到达5个,结束线程");

            }
        }).start();
        //service.shutdown();

    }


}

输出结果:

Thread-0is running
进入ExceptionInterrupt2 类中run方法的catch了!
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.question.Test3$1.run(Test3.java:33)
	at java.lang.Thread.run(Thread.java:748)
Thread-0is ending

阻塞线程会自动抛出异常,有点类似上面我们写的第二个例子,因为捕捉到了异常所以不会继续执行。

当一个线程处于中断状态时,如果再由wait、sleep以及jion三个方法引起的阻塞,那么JVM会将线程的中断标志重新设置为false,并抛出一个InterruptedException异常,然后开发人员可以中断状态位“的本质作用-----就是程序员根据try-catch功能块捕捉jvm抛出的InterruptedException异常来做各种处理,比如如何退出线程。总之interrupt的作用就是需要用户自己监视线程状态isinterrupted并进行处理。

五、总结

  • stop与interrupt
  • 非阻塞线程interrupt(手动抛异常)
  • 阻塞线程interrupt

猜你喜欢

转载自blog.csdn.net/xcymorningsun/article/details/88017179