聊起中断,大家可能最熟悉的例子就是线程休眠。下面就是一个线程休眠的 demo,在这个例子中,当我们调用 sleep 方法,该方法将会抛出一个需要捕获的中断异常,这里捕获该异常并直接返回。

        for (int i = 0; i < somethings.size(); i  ) {// 休眠 4 stry {Thread.sleep(4000);} catch (InterruptedException e) {// 抛出中断异常return;}// 输出System.out.println(somethings.get(i));}

除了 InterruptedException 中断异常,另外还有三个中断相关的方法,三个方法都与线程相关。

  • thread#interrupt
  • Thread#interrupted
  • thread#isInterrupted

interrupt 方法用于中断线程,但是并不是说该方法就能直接使线程停止

下面使用 interrupt 中断线程,这里我们期望中断直接停止子线程输出。但是当主线程调用子线程 interrupt 方法,子线程并却没有被终止,还在继续打印数字。

        Runnable interruptedTask=new Runnable() {@Overridepublic void run() {for (int i = 0; i <Integer.MAX_VALUE ; i  ) {System.out.println(i);}}};Thread interruptThread=new Thread(interruptedTask);interruptThread.start();// 休眠 5 s,TimeUnit.SECONDS.sleep(2);// 中断当前线程interruptThread.interrupt();// 再次休眠,观察子线程TimeUnit.SECONDS.sleep(2);

引用 Java 官方对于中断的解释:

An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate

中断仅仅只是表明这个线程可以停止,但是线程是否停止完全取决于线程自己。只有线程相互协作,才能更好的停止线程。

每个线程都包含一个内部标志,用来表示中断状态。调用线程的 interrupt 方法将会设置该状态位,对于 Thread#sleep 等阻塞方法,将会抛出 InterruptedException ,并清除中断标志。

我们可以使用 thread#isInterruptedThread#interrupted 检查中断状态。但是需要注意,两个方法存在一些区别,Thread#interrupted 为静态类方法,该方法检测到中断之后就会清除中断标志。

上面的方法我们只要加上中断状态判断就也可以停止线程。

        Runnable interruptedTask=new Runnable() {@Overridepublic void run() {for (int i = 0; i <Integer.MAX_VALUE ; i  ) {// 一旦检测到中断标志,停止线程if(Thread.interrupted()){System.out.println("interrupted!!!!");break;}System.out.println(i);}}};Thread interruptThread=new Thread(interruptedTask);interruptThread.start();// 休眠 5 s,TimeUnit.SECONDS.sleep(2);// 中断当前线程interruptThread.interrupt();// 再次休眠,观察子线程TimeUnit.SECONDS.sleep(2);}

中断最佳实践

不要随意『吃掉』中断异常

由于中断异常是一个 checked exception,我们不得不需要处理该异常。如果我们可以保证该异常不影响应用,我们可以直接『吃掉』这个异常。其他情况下我们需要正确处理这个异常。

最简单的做法就是不处理该异常,直接向上抛出中断异常,让上层调用者决定如何处理。

但是有些情况下,却不适合上面的做法,这种情况下我们需要在 catch 中处理中断。如果实在不知道如何处理,那就是记录该异常,并使用日志方式输出。

中断不会停止阻塞 IO

上面我们说到,对于一些阻塞方法如 Thread#sleep ,将会抛出中断异常。但是对于 Socket 等阻塞 IO 调用,并不会抛出这个异常。也就是说中断并不会停止阻塞 IO 的调用。

这是因为当调用 Thread#sleep 等阻塞方法时,Java 线程状态将会从 RUNNABLE 转变为 TIMED_WAITINGWATTING。而当线程阻塞在 IO 读取时,Java 线程实际状态却还是 RUNNABLE。如果你对这个线程状态还有疑惑,可以阅读下这篇文章 面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?,深入理解一下线程状态。

本文首发于studyidea.cn

欢迎关注我的公众号:程序通事,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn

协作,才能更好的中断线程相关推荐

  1. JAVA中断线程的方法

    JAVA中断线程的方法 Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit 这些终止线程运行的方法已经被废弃 ...

  2. java 线程 通过interrupted_Java线程的传说(1)——中断线程Interrupted的用处

    中断线程 -- interrupt() 一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法: ...

  3. 为什么不推荐使用 stop、suspend 方法中断线程?

    以下文章来源方志朋的博客,回复"666"获面试宝典 作者 | 浪舟子 来源 | https://blog.csdn.net/qq_40400960/article/details/ ...

  4. c++并发编程实战_Java 并发编程实战:JAVA中断线程几种基本方法

    一个多线程Java程序,只有当其全部线程执行结束时(更具体地说,是所有非守护线程结束或者某个线程调用system.exit()方法的时候) ,才会结束运行.有时,为了终止程序或者取消一个线程对象所执行 ...

  5. InterruptedException和中断线程的解释

    如果没有将InterruptedException检查为异常,则可能甚至没人会注意到它–实际上,这些年来可以防止出现几个错误. 但是由于必须对其进行处理,因此许多人不正确或不加考虑地处理它. 让我们以 ...

  6. InterruptedException和中断线程的说明

    如果没有将InterruptedException检查为异常,则可能甚至没人会注意到它-这实际上可以防止这些年来的几个错误. 但是由于必须对其进行处理,因此许多人不正确或不加考虑地处理它. 让我们以一 ...

  7. Java线程中断机制-如何中断线程

    Java线程中断机制-如何中断线程 版权声明:本文为博主原创文章,欢迎指正或者转载. https://blog.csdn.net/qq_38663729/article/details/7823264 ...

  8. 为什么强烈不推荐使用stop、suspend方法来中断线程?

    点击关注公众号,实用技术文章及时了解  作者:浪舟子  blog.csdn.net/qq_40400960/article/details/112651249 我们知道像stop.suspend这几种 ...

  9. JAVA线程的应用实例(运用2种中断线程方式,基于实现进度条为例)

    Java内置了对多线程的支持,那些在其他语言中必须由手工完成的工作,现在都可以由Java自动处理.我们进入多线程就像进入了一个全新的领域,因为它的编程思想打破了传统,传统的程序代码一般都是从上到下一条 ...

  10. java中断线程_Java线程中断机制-如何中断线程

    介绍: 对于线程一共分为五个状态:新建状态,就绪状态,阻塞状态,运行状态,死亡状态,有时候把阻塞状态又分为同步阻塞和等待阻塞. 有时想让主线程启动的一个子线程结束运行,我们就需要让这个子线程中断,不再 ...

最新文章

  1. sklearn学习(二)
  2. 开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽!
  3. python 条形图_Python数据可视化:基于matplotlib绘制「堆积条形图」
  4. GaussDB(for MySQL)如何快速创建索引?华为云数据库资深架构师为您揭秘
  5. 湖南科技大学计算机男女比例,湖师大文学院新生男女比例1:9 成了“女儿国”...
  6. (三)使用Keras构建移动风格迁移CycleGAN
  7. python colorbar 0变白色_Python matplotlib更改超过colorbar范围的值的默认颜色
  8. 黑马程序员—一张帖看完黑马所有学科、班级就业薪资贴
  9. 继“世界性别平等大会”圆满召开后,喀拉拉邦首席部长为“性别平等园区”揭幕
  10. 拭血长短句手札【2013-2017】微信公众号 shixuemp
  11. 【Python 3.7】熟食店:创建一个名为 sandwich_orders 的列表,在其中包含各种三明治的名 字;再创建一个名为 finished_sandwiches 的空列表……
  12. 企业办理icp许可证有没必要-icp许可证
  13. 概率密度求解定理_从贝叶斯定理到概率分布:综述概率论基本定义
  14. Kali Linux 初探
  15. 薅羊毛软件-抢福袋源码分享
  16. linux cat命令的作用,Linux命令cat使用详解
  17. 深入理解散列函数和散列表
  18. [CDLinux]制作U盘CDLinux系统启动盘
  19. 苹果六电池_苹果深夜发布新笔记本,性能太强了
  20. 全国行政区划码(国家统计局数据)

热门文章

  1. Office Tip(1) : Split the Screen
  2. [转]通过崩溃地址找错误行数之Delphi版
  3. 多台服务器同时装系统吗,多服务器同时安装操作系统
  4. 疫情之下,你有多久没回过家了?
  5. python实现不使用额外空间去除重复元素
  6. 中文分词的python实现----HMM、FMM
  7. 使用python原生态的min和max函数实现升序排序和降序排序
  8. Java并发编程中锁的正确使用方法
  9. 浅谈volatile的原理
  10. mysql从库追主库日志_centos 6.5设置mysql主从同步过程记录