线程中断

线程中断总结

在Java中,停止一个线程的主要机制是中断,中断并不是强迫终止一个线程,它是一种协作机制,是给线程传递一个取消信号,但是由线程来决定如何以及何时退出。

Thread类定义了如下方法:

interrupt()对线程的影响与线程的状态和在进行的IO操作有关,我们先考虑线程的状态:

  • RUNNABLE:线程在运行或具备运行条件只是在等待操作系统调度
  • WAITING/TIMED_WAITING:线程在等待某个条件或超时
  • BLOCKED:线程在等待锁,试图进入同步块
  • NEW / TERMINATED:线程还未启动或已结束

RUNNABLE

如果线程在运行中,且没有执行IO操作,interrupt()只是会设置线程的中断标志位,没有任何其它作用。线程应该在运行过程中合适的位置检查中断标志位,如:

复制代码
复制代码

WAITING/TIMED_WAITING

线程执行如下方法会进入WAITING状态:

执行如下方法会进入TIMED_WAITING状态:

在这些状态时,对线程对象调用interrupt()会使得该线程抛出InterruptedException,需要注意的是,抛出异常后,中断标志位会被清空,而不是被设置。比如:

复制代码
复制代码

输出为:

捕获到InterruptedException,通常表示希望结束该线程,线程大概有两种处理方式:

    • 向上传递该异常,这使得该方法也变成了一个可中断的方法,需要调用者进行处理。
    • 有些情况,不能向上传递异常,比如Thread的run方法,它的声明是固定的,不能抛出任何受检异常,这时,应该捕获异常,进行合适的清理操作,清理后,一般应该调用Thread的interrupt方法设置中断标志位,使得其他代码有办法知道它发生了中断。

BLOCKED

如果线程在等待锁,对线程对象调用interrupt()只是会设置线程的中断标志位,线程依然会处于BLOCKED状态,也就是说,interrupt()并不能使一个在等待锁的线程真正"中断"。
使用synchronized关键字获取锁的过程中不响应中断请求,这是synchronized的局限性。如果这对程序是一个问题,应该使用显式锁。

总结

interrupt方法不一定会真正"中断"线程,它只是一种协作机制,如果不明白线程在做什么,不应该贸然的调用线程的interrupt方法,以为这样就能取消线程。
对于以线程提供服务的程序模块而言,它应该封装取消/关闭操作,提供单独的取消/关闭方法给调用者,外部调用者应该调用这些方法而不是直接调用interrupt。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 概述 引入 我们之前介绍了Callable和Runnable接口,Callable接口在使用时可能会遇到只支持Ru...
    鹏程1995阅读 292评论 0 0
  • 一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。...
    阿敏其人阅读 2,626评论 0 13
  • 一、wait--notify--sleep Object obj = new Object(); obj.wait...
    fe0180bd6eaf阅读 358评论 0 1
  • 一、并发 进程:每个进程都拥有自己的一套变量 线程:线程之间共享数据 1.线程 Java中为多线程任务提供了很多的...
    SeanMa阅读 2,568评论 0 11
  • 文章作者:阮一峰老师 原文链接 各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法。...
    RainingMan阅读 1,460评论 0 0