Java 并发:线程中断-interrupt
一直以为执行了interrupt方法就可以让线程结束,并抛出InterruptedException. 今天看了Java并发编程实战的第七章发现并不是这么回事,在这章的开头就提到
要使任务和线程能安全、快速、可靠地停止下来,并不是一件容易的事。Java没有提供任何机制来安全地终止线程。但它提供了(Interruption),这是一种协作机制,能够使一个线程终止另一个线程的当前工作
如上提到的是协作,而不是强制。因为如果需要被中断的线程任务实现没有准守这样的协作约定,那么其他线程就没有办法通过interrupt去中断它。比如下面的foreverThread就没有对interrupt设置的boolean变量进行检测。
Thread foreverThread = new Thread(new Runnable() {
@Override
public void run() {
int t = ;
for (int i = ; i < ; i++) {
i--;
if (t++ % == ) {
System.out.println(".");
}
}
}
});
foreverThread.start();
foreverThread.interrupt();
如书中所述,每个线程都有一个boolean类型的中断状态,我们可以通过调用线程的interrupt方法来设置这个值为true,并通过isInterrupted方法来检测这个值是否被置为true。这样当一个线程(比如主线程)通过调用另外一个(比如任务)线程interrupt方法,然后这个任务线程内有检测该boolean值是否置位的逻辑,如果为true这中止当前的工作,然后按照库方法那样抛出一个InterruptException来提示当前任务执行被中断了。因为interrupt设置这个boolean变量是线程体相关的,一次设置后它会一直存在于线程体,这样如果不把它重新置为false,那么执行后续其他会检测这个变量的操作就会立即退出抛出InterruptException。出于这样的原因,当检测到这个boolean标记被设为true后,在要抛出InterruptException之前,还要通过调用Thread.interrupted()方法来重置这个boolean标记(即设为false)以免影响后续的操作(这也表示执行这个动作的这部分代码处理了这次中断请求,至于怎么处理,一般就是上文所说的抛出InterruptException)。
阻塞库方法,例如Thread.sleep和Object.wait等,都会检测线程何时中断,并且在发现中断时提前返回。它们在响应中断时执行的操作包括:清除中断状态,抛出InterruptException,表示阻塞操作由于中断而提前结束。
线程实例的interrupt方法用于设置boolean标记,静态的Thread.interrupted方法用于清除boolean标记(即置为false,同时返回以前的boolean值)下面是一个实例:
Thread iThread = Thread.currentThread();
iThread.interrupt();
System.out.println(iThread.isInterrupted());
System.out.println(Thread.interrupted());
System.out.println(iThread.isInterrupted());
输出如下:
true
true
false
使用静态的interrupted时应该小心,因为它会清除当前线程的中断状态。如果在调用interrupted时返回了true,那么除非你想屏蔽这个中断,否则必须对它进行处理——可以抛出InterruptedException,或者通过再次调用interrupt来恢复中断
如果我们在检测到interrupt中断后,抛出异常却不调用interrupted清除标记,那么会影响到以后的其他可中断调用:
BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
Thread iThread = Thread.currentThread();
iThread.interrupt();
System.out.println(iThread.isInterrupted());
try {
queue.take();
} catch (InterruptedException e) {
System.out.println("thread is interrupted, isInterrupted:" + iThread.isInterrupted());
}
输出:
true
thread is interrupted, isInterrupted:false
运行以上代码片段,程序会立即结束而不会再queue.take()上等待。在库函数抛出InterruptException后,通过isInterrupted检测可以发现中断boolean标记已经被清除(置为false)
Java 并发:线程中断-interrupt的更多相关文章
- Java并发——线程中断学习
1. 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返 ...
- java之线程中断——interrupt
如下图所示,interrupt()方法并没有成功的中断我们的线程. 为了便于理解,其实可以这样来类比(注意,只是类比,实际情况并不完全是这样):Thread类中有一个boolean的标志域用来表示线程 ...
- Java 并发 线程同步
Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...
- Java 并发 线程属性
Java 并发 线程属性 @author ixenos 线程优先级 1.每当线程调度器有机会选择新线程时,首先选择具有较高优先级的线程 2.默认情况下,一个线程继承它的父线程的优先级 当在一个运行的线 ...
- Java 并发 线程的优先级
Java 并发 线程的优先级 @author ixenos 低优先级线程的执行时刻 1.在任意时刻,当有多个线程处于可运行状态时,运行系统总是挑选一个优先级最高的线程执行,只有当线程停止.退出或者由于 ...
- Java 并发 线程的生命周期
Java 并发 线程的生命周期 @author ixenos 线程的生命周期 线程状态: a) New 新建 b) Runnable 可运行 c) Running 运行 (调用 ...
- 线程中断 interrupt 和 LockSupport
本文章将要介绍的内容有以下几点,读者朋友也可先自行思考一下相关问题: 线程中断 interrupt 方法怎么理解,意思就是线程中断了吗?那当前线程还能继续执行吗? 判断线程是否中断的方法有几个,它们之 ...
- 从JDK源码角度看java并发线程的中断
线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...
- java并发:中断一个正在运行的线程
要使任务和线程能安全可靠地停止,并不是一件很容易的事情,java没有提供任何机制来安全地终止线程,那么我们该怎么办呢? 下面我们先来了解一下java中的中断机制: java中断机制是一种协作机制,也就 ...
随机推荐
- [JS] js 判断用户是否在浏览当前页面
var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : ...
- jmeter 之 BeanShell PostProcessor跨线程全局变量使用
BeanShell PostProcessor是用户对一些变量的操作,操作方法很灵活,大概原理是通过parameters传回来对象,然后在script中对对象进行操作 场景:从登陆接口中获取token ...
- 个人KPI制定
1.工作量 1.1 能独立完成工作优先级 1.2 能独立预估工作时间 2.工作质量 2.1 项目按时完成没有延期 2.2 交付件质量 2.2.1 测试用例设计没有明显遗漏 2.2.2 测试bug符合规 ...
- Memcached安装教程及使用
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载 Table of contents 安装 使用 在spring中使用 安装 下载下来m ...
- leetcode-268-Missing Number(异或)
题目描述: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is ...
- C#-WebForm-css box-shadow 给边框添加阴影效果
box-shadow介绍 css3可以使用 box-shadow 属性轻松地为元素添加阴影效果,box-shadow可以设定多组效果,每组参数值以逗号分隔. 语法: box-shadow:x-shad ...
- 直接线性变换解法(DLT)用于标定相机
直接线性变换法是建立像点坐标和相应物点物方空间坐标之间直接的线性关系的算法.特点:不需要内外方位元素:适合于非量测相机:满足中.低精度的测量任务:可以标定单个相机. 1 各坐标系之间的关系推导直接线性 ...
- python全栈开发_day15_函数回调和模块
一:函数回调 def a(fn=None): print("run1") if fn: fn() print("run 2") def b(): print(& ...
- 【Three.js】实现随心所欲的展示外部三维模型
1.概要 最近学习Three.js,尝试加载一些3d max导出的obj.stl模型,在展示模型的时候遇到了一些问题,模型的尺寸.位置和旋转角度每次都靠手工调整,非常的不方便,就想着写一个方法来随心所 ...
- linux 安装php bz2扩展
折腾了半天,最大的坑就是我是用lnmp一键安装php环境,php7下面没有ext文件夹,有个include下面虽然有个ext 但是里面没有需要的bz2 也尝试去pecl 和 pear 上面去找 无 ...