一、前言

之前本人写了一篇防止Controller中的线程被重复调用的文章,大概代码如下:

//sonarqube检查要求static变量必须是final,为避开检查,使用final HashMappublic final static HashMap threadMap = new HashMap<>();--------------------------------------------------Thread nowThread = threadMap.get("nowThread");if(nowThread != null && nowThread.isAlive()){    LOG.info("当前存在正在执行的线程,本次线程不执行,请稍后再试");    return;}else{    threadMap.put("nowThread",Thread.currentThread());}//主要代码省略......//线程执行完毕,置空threadMap.put("nowThread",null);

后来,由于担心这个线程会卡死,导致后续正常调用该线程的操作无法进行,因此加了个手动停止线程运行的方法(interrupt):

//传入一个type参数,如果为3,中断上一个线程的执行if(type == 3){ try{   Thread nowThread = threadMap.get("nowThread");   //中断上一个线程   nowThread.interrupt();   threadMap.put("nowThread",null);   String backMsg = "线程interrupt成功!";   LOG.info(backMsg);   return; }catch(Exception e){   threadMap.put("nowThread",null);   String backMsg = "线程interrupt失败,只将map置空!";   LOG.error(backMsg,e);   return; }}

然而,仅仅这样并不能停止线程运行。

二、停止线程运行的方法

  1. 使用标志位停止线程,还行,但是遇到sleep时的线程就无法停止了,必须等线程sleep结束、运行到判断标志位步骤时才行。

  2. 使用stop()停止线程,不安全,已不推荐使用。会立即停止线程运行,会使一些清理性的工作的得不到完成,如文件,数据库等的关闭;会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。

  3. 使用interrupt()中断线程,需要配合代码逻辑实现停止线程。

需要注意,调用 interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不是真的停止线程;如果直接将线程停止,就会和stop一样出现问题。

因此还需要配合代码逻辑实现。

三、正确使用interrupt停止线程运行

先看下例子:

public static void main(String[] args) throws InterruptedException{  Thread t1 = new Thread(){    @Override    public void run(){      //一个循环线程      while(true){        //一种结束情况        if(this.currentThread().isInterrupted()){          System.out.println("线程被打断,停止运行");          break;        }else{          System.out.println("线程在运行");          try{            //Thread.sleep(0L);            Thread.sleep(1000L);          }catch(InterruptedException e){            //另一种结束情况            System.out.println("线程睡眠时被打断,停止运行");            break;          }        }      }    }  };  t1.start();  Thread.sleep(5000L);  t1.interrupt();  System.out.println("主线程打断t1完成");}

上方的代码中,先启动一个线程,然后主线程在5秒后打断它,它有两种停止情况:

  1. 执行if判断时,发现标志位为true,因此执行break,之后停止运行。

  2. 线程还在sleep,此时发现被打断,会抛出InterruptedException,然后被catch到,执行break,之后停止运行。

结合实际代码,如果线程中不需要sleep,则判断isInterrupted()即可;

如果线程中存在sleep,则catch中使用break、return之类的停止线程即可;

当然也可以两种都写。

本人的代码中有sleep,因此只在catch中加了break,没有判断标志位。

四、总结

  1. 使用interrupt停止线程比标志位停止线程的好处在于,它不仅能通过标志判断是否要停止线程,而且当线程处于sleep状态时,使用interrupt就可以停止线程,而标志位不行。

  2. 使用interrupt停止线程比stop停止线程的好处在于,stop不安全,会产生难以预料的后果,而interrupt不会。

  3. 停止线程时,不仅要直接调用interrupt(),还要写好相应的代码逻辑,一种逻辑与标志位停止线程类似,另一种逻辑要注意在try中写Thread.sleep(当你的线程需要sleep时),在catch中写break、return之类的方法。

PS:之前写sleep时,都是这么写的:

try{ Thread.sleep(5000L);}catch(Exception e){}

现在终于知道应该怎么写了

调用方法try起来的好处_Java:一个重要的停止线程方法——interrupt相关推荐

  1. java executorser 停止_Java使用ExecutorService来停止线程服务

    使用ExecutorService来停止线程服务 之前的文章中我们提到了ExecutorService可以使用shutdown和shutdownNow来关闭. 这两种关闭的区别在于各自的安全性和响应性 ...

  2. 线程停止继续_Java并发学习第二弹:如何正确停止线程?

    线程停止的原则:使用interrupt来通知,而不是强制停止线程 interrupt在英文中实为通知的意思,那么为什么停止线程不直接停止而使用通知呢? 这是因为在java中,我们如果想要停止一个线程, ...

  3. 如何暂停一个正在运行的线程?

    今天把小伙伴问懵了,小刚,你知道怎么停止一个线程吗? 这-,这-,stop? 原来平时小刚这小子只知道创建线程,不知道怎么暂停线程呀~[狗头] 停止线程是在多线程开发中很重要的技术点,比如在多线程持续 ...

  4. 多线程的终止方法(停止线程)

    多线程的终止方法 多线程的终止共有3种方法 run方法执行结束,正常退出 异常终止 暴力终止 停止线程 停止线程是多线程中的一个重要技术点,本篇文章将对线程的停止操作进行详细讲解. Thread类中是 ...

  5. setInterval和setTimeout停止的方法

    先来了解 setInterval : 1,HTML DOM setInterval() 方法 定义和用法 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setI ...

  6. 线程中断机制 interrupt、isInterrupted、interrupted方法

    ①. 什么是中断 ①. 一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,所以,Thread.stop.Thread.suspend.Thread. resume都已经被废弃了 ② ...

  7. 为什么不要用stop方法停止线程?

    线程启动完毕后,在运行时可能需要终止,Java提供的终止方法只有一个stop,但是我不建议使用这个方法,因为它有以下三个问题:(1)stop方法是过时的从Java编码规则来说,已经过时的方法不建议采用 ...

  8. shell实例第19讲:一个脚本中调用另一个脚本的3种方法

    在Shell脚本中调用另一个脚本(3种方法) 准备:主脚本是second.sh,主脚本中调用first.sh 方法1:exec(1)执行方式:exec /home/weibo/shell_test/s ...

  9. 定义一个 圆形 Circle类 , 定义其中的长度length属性,定义一个求面积getArea()的方法。 并编写一个测试类,进行长度的赋值和展示,并调用求面积方法展示面积值。

    定义一个 圆形 Circle类 , 定义其中的长度length属性,定义一个求面积getArea()的方法. 并编写一个测试类,进行长度的赋值和展示,并调用求面积方法展示面积值. public cla ...

最新文章

  1. Android Gatekeeper流程深度解剖
  2. [转]CNN目标检测(一):Faster RCNN详解
  3. 网络互撕是群体极化的典型症状
  4. SpyEye on Android
  5. STANDBY REDO LOG
  6. 行业领先!5G投资1100亿! 20个中国移动5G成功案例分享( 业绩+案例 )
  7. 五年技术工作的一点点感悟
  8. MGWR多尺度地理加权回归
  9. python如何爬有道翻译_基于python爬取有道翻译过程图解
  10. 将外国文献翻译成中文
  11. 坐标上海,我看见这群开发者用热爱改变世界
  12. dbeaver连接hive3.1.2,不需添加驱动
  13. 给零基础初学者推荐的10个Python免费学习网站,赶快收藏
  14. 带节点的曲线,可以鼠标拖动节点,类似PS
  15. 微信企业号手机端清理缓存
  16. 深度学习升级打怪之self attention笔记
  17. 关于 QML Tumbler 自定义日历在响应onWheel事件后,其他原有mouse事件无法响应
  18. 记录M1Mac基础的Command快捷键
  19. 微信小程序云开发实现问卷调查的创建与填写
  20. 11g-sql plan management

热门文章

  1. 取消关机shutdown -c
  2. kettle升级jetty10实验(未完成jaas认证)
  3. 编程工作怎么样手工问号
  4. python如何生成excel文件夹_用python脚本通过excel生成文件夹树结构
  5. 虚拟机Centos报corruption of in-memory data detected错误的恢复
  6. vue ---- 组件
  7. java便签小程序原码_localStorage实现便签小程序
  8. JasperReport报表导出PDF中文不显示的问题
  9. elementUI使用之table表格如何给行元素添加点击事件
  10. Swagger2 生成API文档时泛型总是显示不出来的问题