在很多时候我们需要中断或者取消一些任务,在Java中并没有提供一些好的方法来终止线程。

中断原因

我们的任务或者线程一般情况下都会让它正常的执行直到结束,然而有时候也有可能我们需要提前结束这个任务或者线程。但是一个任务或者线程的执行涉及系统、内存、栈、数据等的完整性,要提前结束并不简单,在Java中也没有提供好的安全地终止线程

取消的原因有很多比如用户取消、一定时间未成功提前结束、错误、服务器关闭等,一个好的软件特点之一就是能够很完善的处理失败、关闭和取消的过程。

中断方法一:中断标志位

我们可以设置一个已关闭的标志位,当任务或者线程运行的时候先判断标志位的状态,如果是已经关闭那个这个任务或者线程就直接结束,不过这个标志位需要用volatile关键字修饰,否则可能其他线程已经修改了任务可能仍然在运行。

这种方法可以解决一部分问题,但是当任务可能会被阻塞的时候就会出现问题,就像之前的生产者、消费者模式,如果生产者通过循环往队列里面加元素,在每次循环之前都要判断中断标志位,如果结束了就不往队列中put数据了,当消费者在某些情况下可能不在消费数据所以会设置标志位为已结束。此时如果阻塞队列是满的,而刚好生产者在put阻塞中,由于消费者不在消费,生产者线程就会永远处于阻塞状态。

中断方法二:Thread.interrupt()

上一个中断方法在遇到阻塞方法时就会出现永久阻塞状态的问题,所以Java的Thread提供了一个boolean类型的中断状态,通过interrupt方法可以设置状态为中断,isInterrupted方法会返回中断状态,静态的interrupted方法会清除当前线程的中断状态,并返回它之前的值,这是清除中断状态的唯一方法。

一些阻塞方法如Thread.sleep、Object.wait、阻塞队列的take、put方法都会检查线程中断状态,并且在发现中断时提前返回,他们响应中断时执行的操作包括:清除中断状态,抛出InterruptedException,表示阻塞操作因为中断而提前操作,这就是这些方法都会抛出InterruptedException的原因,反之如果抛出InterruptedException则说明线程被中断,接受到这个信息后我们可以方便的处理后续流程。

interrupt方法并不会真正的中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一个合适的时刻中断自己,这样才能保证数据结构不会被破坏。同时要小心调用interrupted方法,它会清除当前线程的中断状态,所以在方法的返回值是true时除非你本来想屏蔽这个中断,否则必须要处理,可以抛出InterruptedException或者再次调用interrupt中断线程。

中断方法三:利用Future

可以把任务封装成一个Future,Future中有一个方法“boolean cancel(boolean mayInterruptIfRunning);”如果参数为true并且任务正在某个线程中执行,那么这个线程就能够被中断,如果参数为false则表示如果任务还没有运行那就不要运行(有些任务不处理中断)。

还存在一些情况可能通过以上方法仍然无法中断或取消,比如IO阻塞或者等待获取锁的阻塞,不过Java中也有一些解决办法,比如Socket则是可以通过关闭socket,对于锁可以在Lock类中提供了lockInterruptibly方法,它可以支持在等在一个锁的同时去响应中断信号。

JVM的关闭

JVM关闭也分为正常关闭和强行关闭,强行关闭方式比如杀死JVM进程。这里主要说明的是正常关闭,比如System.exit获取程序正常执行结束。在正常关闭时,JVM会首先调用注册的关闭钩子(通过“Runtime.getRuntime().addShutdownHook();”添加的一些关闭程序时必须执行的方法,比如清理一些临时文件之类的),当钩子关闭完成后JVM会运行终结器,最后停止。JVM关闭并不会关闭正在运行中的线程,而是在JVM关闭完成后强行关闭。如果关闭钩子或者终结器没有执行完成,那么JVM的关闭进程就会被挂起,然后强行关闭JVM。

两个重要知识点:

线程分两种:普通线程和守护线程,jvm启动时创建的线程除了主线程外都是守护线程,当创建一个线程时新线程会继承状态,所以主线程默认情况下创建的线程都是普通线程。

当一个线程退出时JVM会检查其他正在运行的线程,如果所有都是守护线程,那么JVM会执行正常退出操作。

终结器:垃圾回收器对那些定义了finalize方法的对象在回收后会调用finalize方法,不过finalize方法有性能问题,所以现在已经避免使用。

总结

启动一个任务或线程很简单,但是要提前取消或者关闭却比较复杂,一个好的软件是应该能够很好的支持取消和关闭的。

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

线程结束后会自动关闭_多线程学习之如何中断线程相关推荐

  1. pthread_detach():主线程与子线程分离,子线程结束后,资源自动回收

    https://github.com/Rtoax/test/tree/master/c/glibc/pthread 目录 前言 pthread_join() pthread_detach() 前言 1 ...

  2. c++多线程结束后需要释放_缓刑结束后是否需要继续坐牢?

    刑事案件的刑罚结果分为两种:主刑.附加刑:而主刑的种类包括死刑.徒刑.管制刑.附加刑种类包括罚金.没收财产.剥夺政治权力.那么什么情况下可以判处缓刑呢? 从刑种上,只有主刑中的徒刑可以判处缓刑,而徒刑 ...

  3. C++多线程学习(三)——线程同步之条件变量

    前面学习了互斥量似乎我们就可以多线程编程了,多线程也不过如此嘛.然而我们上手coding,用多线程来结局我们实际需求就会发现,似乎多线程也不是很好用.因为我们实际对于多线程的需求,往往线程都是whil ...

  4. python如何在所有线程结束后执行最后操作_Python线程的生命周期

    在线程的生命周期中,从创建到执行以及最终终止,线程通常处于四种状态之一:开始态.可调度状态.阻塞态和终止态. 父线程和子线程 当一个新的进程或程序开始运行时,它将以一个线程开始,这个线程被称为主线程. ...

  5. Java多线程学习(八)线程池与Executor 框架

    历史优质文章推荐: Java并发编程指南专栏 分布式系统的经典基础理论 可能是最漂亮的Spring事务管理详解 面试中关于Java虚拟机(jvm)的问题看这篇就够了 目录: [TOC] 本节思维导图: ...

  6. java线程同步机制有哪些_多线程同步机制包括哪些,java线程同步机制

    多线程同步机制包括哪些什么是多线程同步机制,多线程同步机制包括:1.临界段用于实现"独占占有":2.信号量用于跟踪有限的资源:3.互斥是核心对象,可以实现不同线程之间的" ...

  7. vb.net 线程偶尔不会自动关闭_C# 多线程系列(7)手动线程通知

    区别与示例 AutoResetEvent 和 ManualResetEvent 十分相似.两者之间的区别,在于前者是自动(Auto),后者是手动(Manua). 你可以先运行下面的示例,再测试两者的区 ...

  8. python结束后找什么工作_python学习结束后找什么工作?

    python学习结束后找什么工作?Python前景怎么样?当你在学习这门语言的时候,你会不会担心以后找不到一份满意的工作?事实上,人生当中,每一次的学习,最后都会让你通过这项技能,让你遇到适合自已的工 ...

  9. Java多线程学习六:使用线程池比手动创建线程好在那里以及常用线程池参数的意义

    为什么要使用线程池 首先,回顾线程池的相关知识,在 Java 诞生之初是没有线程池的概念的,而是先有线程,随着线程数的不断增加,人们发现需要一个专门的类来管理它们,于是才诞生了线程池.没有线程池的时候 ...

  10. java 任务池_多线程的应用-异步任务线程池的简单实现

    对于服务端的应用而言,经常会出现比如定时任务,或者任务的异步执行,熟悉Java开发的开发者,经常会使用Executors类,其提供了4种不同的线程池: ​newCachedThreadPool, ne ...

最新文章

  1. Oracle数据库文件坏块损坏的恢复方法
  2. visual studio 2010 professional , premium, ultimate各版本功能对比
  3. ioslabel阴影_UILabel的内阴影
  4. 技术分享 | jaeger链路日志实现
  5. [Nikon D80]樱花盛开的校园
  6. undertow 怎么创建线程_为什么很多SpringBoot开发者放弃了Tomcat,选择了Undertow
  7. php larve,封装composer包,实现thinkphp、larverl、yii框架中使用(使用框架实现回调方法)...
  8. Leetcode每日一题:101.symmetric-tree(对称二叉树)
  9. Windows环境与Linux环境条件宏
  10. 系列文章--WF学习资料汇总
  11. NB-IoT移远BC95使用小结
  12. HP M280 鼠标驱动
  13. JUCE 中的音频编解码
  14. android语言包,安卓系统添加多国语言包
  15. 大数据讲课笔记5.5 MR案例——倒排索引
  16. ps渐隐在哪里以及ps渐隐知识点总结
  17. 这一周我学习了什么(一)
  18. Sick编码器CanOpen通信
  19. 许昌学院计算机学院张伶俐,【优秀毕业生故事系列】之四:厉害了,我的班!...
  20. html标识标志相关符号

热门文章

  1. 绝对路径与相对路径cd命令的使用
  2. 十七 、二叉树的概念
  3. Team Foundation 使用第三方比较工具
  4. WebsResponse
  5. 【OpenCV学习笔记】【函数学习】三(cvGetCaptureProperty函数)
  6. 普通卷积、转置卷积、空洞卷积(dilated convolution、Atrous Convolution)
  7. 函数和结构(C++)
  8. ArcGIS绘图注意事项(1)
  9. IDL | 语句练习
  10. 【数据、软件共享】年鉴,夜间灯光,土地数据(永久更新)