开局之前

别用stop,停止线程,要用通知让他停止的方式,然后啥时候停止 让他把自己的事情处理完。
image.png

俩阶段删除

先执行interupt 然后在run方法中判断是否已经终止的标志位

为什么弃用stop:

  1. 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
  2. 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。

例如,存在一个对象 u 持有 ID 和 NAME 两个字段,假如写入线程在写对象的过程中,只完成了对 ID 的赋值,但没来得及为 NAME 赋值,就被 stop() 导致锁被释放,那么当读取线程得到锁之后再去读取对象 u 的 ID 和 Name 时,就会出现数据不一致的问题,如下图:
35 | 两阶段终止模式:如何优雅地终止线程? - 图2

  1. public class InterruptThread1 extends Thread{
  2. public static void main(String[] args) {
  3. try {
  4. InterruptThread1 t = new InterruptThread1();
  5. t.start();
  6. Thread.sleep(200);
  7. t.interrupt();
  8. } catch (InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. @Override
  13. public void run() {
  14. super.run();
  15. for(int i = 0; i <= 200000; i++) {
  16. //判断是否被中断
  17. if(Thread.currentThread().isInterrupted()){
  18. //处理中断逻辑
  19. break;
  20. }
  21. System.out.println("i=" + i);
  22. }
  23. }
  24. }

线程池也是俩阶段关闭?

image.png
也是俩阶段 ,执行完关闭之后 其实线程池还没关, 还要不断循环awaitTermination 来判断是否嗝屁。

思考题

必须用volatile