1、原理介绍:

使用interrupt来通知,而不是强制

在Java中,最好的停止线程的方式是使用中断 Interrupt,但是这仅仅是会通知到被终止的线程“你该停止运行了”,被终止的线程自身拥有决定权(决定是否、以及何时停止),这依赖于请求停止方和被停止方都遵守一种约定好的编码规范。

任务和线程的启动很容易。在大多数时候,我们都会让它们运行直到结東,或者让它们自行停止。然而有时候我们希望提前结東任务或线程或许是因为用户取消了操作,或者服务要被快速关闭,或者是运行超时或出错了。要使任务和线程能安全、快速、可靠地停止下来,并不是一件容易的事。Java没有提供任何机制来安全地终止线程。但它提供了中断( Interruption这是一种协作机制,能够使一个线程终止另一个线程的当前工作)。

这种协作式的方法是必要的,我们很少希望某个任务、线程或服务立即停止,因为这种立即停止会使共享的数据结构处于不一致的状态。相反,在编写任务和服务时可以使用一种协作的方式:当需要停止时,它们首先会清除当前正在执行的工作,然后再结束。这提供了更好的灵活性,因为任务本身的代码比发出取消请求的代码更清楚如何执行清除工作。

生命周期结束(End-of-Lifecycle)的问题会使任务、服务以及程序的设计和实现等过程变得复杂而这个在程序设计中非常重要的要素却经常被忽略。一个在行为良好的软件与勉强运的软件之间的最主要区别就是,行为良好的软件能很完善地处理失败、关闭和取消等过程。


 

2、如何正确停止线程

  •   线程通常在什么情况停止普通情况。
    • 执行完所有代码
    • 有异常未捕获。

 


 

3、使用interrupt停止的几种情况。

  • 最普遍的情况
复制代码
/**  * @data 2019/11/9 - 下午8:07  * 描述:run方法内没有sleep或wait方法时,停止线程  */public class RightWayStopThreadWithoutSleep implements Runnable{     @Override     public void run() {         int num = 0;         while(num<=Integer.MAX_VALUE/2 && !Thread.currentThread().isInterrupted()){             if(num%10000 == 0)                 System.out.println(num+"是10000的倍数");             num++;         }         System.out.println("任务结束");     }      public static void main(String[] args) throws InterruptedException {         Thread thread = new Thread(new RightWayStopThreadWithoutSleep());         thread.start();         thread.sleep(1000);         thread.interrupt();     } }
复制代码
  • 当停止线程遇到线程阻塞
复制代码
/**  * @data 2019/11/9 - 下午8:07  * 描述:带有sleep的中断线程的方法  */public class RightWayStopThreadWithSleep {     public static void main(String[] args) throws InterruptedException {         Runnable runnable = ()->{             int num = 0;             try {                 while (num<=300 && !Thread.currentThread().isInterrupted()){                     if(num%100 == 0)                         System.out.println(num+"是100的倍数");                      num++;                 }                 Thread.sleep(1000);             } catch (InterruptedException e) {                 e.printStackTrace();             }         };          Thread thread = new Thread(runnable);         thread.start();         Thread.sleep(500);         thread.interrupt();     } }
复制代码
复制代码