上文讲解了Java线程的创建、启动以及停止,在讲到停止线程时说到了Java中断,Java中断是停止线程的一种协作机制,本文打算对Java中断机制进行详细讲解。

在网上搜索Java中断机制,发现两篇好文章,分别如下:Java 理论与实践: 处理 InterruptedException 以及 详细分析Java中断机制,推荐大家仔细阅读。

中断是一种协作机制                                                                                    

必须记住,中断是一种协作机制。当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情。相反,中断是礼貌地请求另一个线程在它愿意并且方便的时候停止它正在做的事情。有些方法,例如 Thread.sleep(),很认真地对待这样的请求,但并不是每个方法一定要对中断作出响应。 您可以随意忽略中断请求,但是这样做的话会影响响应。

中断状态                                                                                                   

每个Java线程都有一个与之相关联的 Boolean 属性,该属性用于表示线程的中断状态,Thread类提供了三个方法用于操作中断状态,这些方法包括:

public static boolean interrupted()

测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

public booleanisInterrupted()   测试线程是否已经中断。线程的中断状态不受该方法的影响。
 public voidinterrupt()  中断线程。

三个方法中,interrupt()方法是唯一能将中断状态设置为true的方法,另外两个方法都是用于检测当前中断状态的方法。

中断的处理                                                                                                 

作为一种协作机制,中断机制不会强求被中断线程一定要在某个点进行处理。实际上,被中断线程只需在合适的时候处理中断即可,如果没有合适的时间点,甚至可以不处理,这时候在任务处理层面,就跟没有调用中断方法一样。

在JDK中,有很多阻塞方法的声明中有抛出InterruptedException异常,这暗示该方法是可中断的,这些方法会检测当前线程是否被中断,如果是,则立刻结束阻塞方法,并抛出InterruptedException异常。如果程序捕获到这些可中断的阻塞方法抛出的InterruptedException或检测到中断后,这些中断信息该如何处理?一般有以下两个通用原则:

  • 如果遇到的是可中断的阻塞方法抛出InterruptedException,可以继续向方法调用栈的上层抛出该异常,如果是检测到中断,则可清除中断状态并抛出InterruptedException,使当前方法也成为一个可中断的方法。
  • 若有时候不太方便在方法上抛出InterruptedException,比如要实现的某个接口中的方法签名上没有throws InterruptedException,这时就可以捕获可中断方法的InterruptedException并通过Thread.currentThread.interrupt()来重新设置中断状态。如果是检测并清除了中断状态,亦是如此。

一般的代码中,尤其是作为一个基础类库时,绝不应当吞掉中断,即捕获到InterruptedException后在catch里什么也不做,清除中断状态后又不重设中断状态也不抛出InterruptedException等。因为吞掉中断状态会导致方法调用栈的上层得不到这些信息。

当然,凡事总有例外的时候,当你完全清楚自己的方法会被谁调用,而调用者也不会因为中断被吞掉了而遇到麻烦,就可以这么做。

不可取消的任务                                                                                           

有些任务拒绝被中断,这使得它们是不可取消的。但是,即使是不可取消的任务也应该尝试保留中断状态,以防在不可取消的任务结束之后,调用栈上更高层的代码需要对中断进行处理。以下代码展示了一个方法,该方法等待一个阻塞队列,直到队列中出现一个可用项目,而不管它是否被中断。为了方便他人,它在结束后在一个 finally 块中恢复中断状态,以免剥夺中断请求的调用者的权利。

public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}

总结                                                                                                          

中断是一种协作机制,利用该机制我们可以构造灵活的线程取消策略,每个线程都可以自行决定它们是可取消的还是不可取消的,以及如何对中断作出响应,如果立即返回会危害应用程序完整性的话,它们还可以推迟中断。

参考:

Java 理论与实践: 处理 InterruptedException:http://www.ibm.com/developerworks/cn/java/j-jtp05236.html

详细分析Java中断机制:http://www.infoq.com/cn/articles/java-interrupt-mechanism

Java并发(基础知识)—— Java中断机制的更多相关文章

  1. java并发基础知识

    这几天全国都是关键时候,放假了,还是要学习啊!很久没有写博客了,最近看了一本书,有关于java并发编程的,书名叫做“java并发编程之美”,讲的很有意思,这里就做一个笔记吧! 有需要openjdk8源 ...

  2. Java 并发基础知识

    一.什么是线程和进程? 进程: 是程序的一次执行过程,是系统运行程序的基本单元(就比如打开某个应用,就是开启了一个进程),因此进程是动态的.系统运行一个程序即是一个程序从创建.运行到消亡的过程. 在 ...

  3. 【Java并发基础】Java内存模型解决有序性和可见性

    前言 解决并发编程中的可见性和有序性问题最直接的方法就是禁用CPU缓存和编译器的优化.但是,禁用这两者又会影响程序性能.于是我们要做的是按需禁用CPU缓存和编译器的优化. 如何按需禁用CPU缓存和编译 ...

  4. java线程基础知识----java线程模型

    转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...

  5. java线程基础知识----java daemon线程

    java线程是一个运用很广泛的重点知识,我们很有必要了解java的daemon线程. 1.首先我们必须清楚的认识到java的线程分为两类: 用户线程和daemon线程 A. 用户线程: 用户线程可以简 ...

  6. 【Java并发基础】Java线程的生命周期

    前言 线程是操作系统中的一个概念,支持多线程的语言都是对OS中的线程进行了封装.要学好线程,就要搞清除它的生命周期,也就是生命周期各个节点的状态转换机制.不同的开发语言对操作系统中的线程进行了不同的封 ...

  7. Java并发基础知识你知道多少?

    并发 https://blog.csdn.net/justloveyou_/article/details/53672005 并发的三个特性是什么? 什么是指令重排序? 单线程的指令重排序靠什么保证正 ...

  8. Java并发--基础知识

    一.为什么要用到并发 充分利用多核CPU的计算能力 方便进行业务拆分,提升应用性能 二.并发编程有哪些缺点 频繁的上下文切换 时间片是CPU分配给各个线程的时间,因为时间非常短,所以CPU不断通过切换 ...

  9. 目录-java并发基础知识

    ====================== 1.volatile原理 2.ThreadLocal的实现原理(源码级) 3.线程池模型以及核心参数 4.HashMap的实现以及jdk8的改进(源码级) ...

  10. java复习基础知识——java保留字

    ava 关键字列表 (依字母排序 共51组): abstract, assert,boolean, break, byte, case, catch, char, class, const, cont ...

随机推荐

  1. mitmproxy 使用mitmdump 过滤请求

    mitmproxy 抓包工具,优点可以使用python进行二次开发,或者进行接口的mock 官网地址:https://www.mitmproxy.org/ 打算用这个最初的需求是,想对app做接口测试 ...

  2. sklearn.metrics.mean_absolute_error

    注意多维数组 MAE 的计算方法 * >>> from sklearn.metrics import mean_absolute_error >>> y_true ...

  3. 数据库(一):事务的特性与事务(在同一个 JVM 中)的传递

    参考文章 https://blog.csdn.net/shuaihj/article/details/14163713 https://blog.csdn.net/shfqbluestone/arti ...

  4. 【leetcode】1052. Grumpy Bookstore Owner

    题目如下: Today, the bookstore owner has a store open for customers.length minutes.  Every minute, some ...

  5. 对Promise的研究3

    Promise.race() Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例. const p = Promise.race([p1, p2, p ...

  6. iText导出PDF(图片,水印,页眉,页脚)

    项目需要导出PDF,导出的内容包含图片和文本,而且图片的数量不确定,在网上百度发现大家都在用iText,在官网发现可以把html转换为PDF,但是需要收费,那就只能自己写了. 在开始之前先在网上百度了 ...

  7. CF576D Flights for Regular Customers 矩阵乘法 + Bitset优化

    %%%cxhscst2's blog Codeforces 576D Flights for Regular Customers(矩阵加速DP) 代码非常优美 + 简洁,学习到了 Code: #inc ...

  8. DB-MDM:MDM/主数据管理 百科

    ylbtech-DB-MDM:MDM/主数据管理 百科 主数据管理(MDM Master Data Management)描述了一组规程.技术和解决方案,这些规程.技术和解决方案用于为所有利益相关方( ...

  9. CSS-同一行的元素高度统一

    一:flex 大法 步骤 设置外部容器 display: flex; 设置内部容器 align-items: stretch; 原理 https://developer.mozilla.org/zh- ...

  10. 精讲 org.w3c.dom(java dom)解析XML文档

    org.w3c.dom(java dom)解析XML文档 位于org.w3c.dom操作XML会比较简单,就是将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效果可能会 ...