Java并发编程实战————恢复中断
中断是一种协作机制,一个线程不能强制其他线程停止正在执行的操作而去执行其他操作。
什么是中断状态?
线程类有一个描述自身是否被中断了的boolean类型的状态,可以通过调用 .isInterrupted() 方法来查看。官方解释如下:
简单来说,这个方法如果返回 true ,那么表示线程已经被中断。
恢复中断
这里提到的 “恢复中断” 绝对不是 “从中断中恢复” 的意思!
在《Java并发编程实战》一书第五章 p78页,首次提到了这个恢复中断的概念,而当我看到第七章的时候才明白这里为什么要恢复中断。
因为中断是一种协作机制,当一个线程阻塞时,我们需要通过另一个线程调用阻塞线程的 interrupt() 方法,来请求阻塞线程取消任务。最简单的阻塞方法就是 Thread.sleep() , 我们来看一下我写的一个简单的例子:
public class Demo_01 {public static void main(String[] args) throws InterruptedException {Thread myTh = new Thread(new TaskDemo());myTh.start();TimeUnit.SECONDS.sleep(3);// 中断myTh线程myTh.interrupt();}
}class TaskDemo implements Runnable {@Overridepublic void run() {try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {System.out.println("捕获到中断异常,当前线程的中断状态是:" + Thread.currentThread().isInterrupted());System.out.println("即将恢复中断... ...");Thread.currentThread().interrupt();System.out.println("中断恢复!中断状态已经是:" + Thread.currentThread().isInterrupted());}}
}
执行结果是:
我们可以看到,interrupt()方法会将线程的中断状态置为true,而任务被中断的时候不仅会抛出一个InterruptedException异常,还会清除中断状态!
这个问题在书中第七章 P114 有所说明:
阻塞库方法,例如Thread.sleep和Object.wait等,都会检查线程何时中断,并且在发现中断时提前返回。它们在响应中断时执行的操作包括:清除中断状态;抛出InterruptedException,表示阻塞操作由于中断而提前结束。
上面的程序中,由于TaskDemo实现Runnable接口,在面对中断请求的时候,无法向上层抛出,必须捕获,如果没有在catch块中调用interrupt()方法,那么中断状态将在清除之后被上层逻辑 “屏蔽”。书中强调,一个健壮的任务执行方法,应该能够正确处理中断请求,而不是屏蔽。
因此,如果不想任务执行时出现的中断被屏蔽,就必须将线程的中断状态恢复,换句话说,就是再次将线程的中断状态置为true!
因为有点绕,所以大多数人可能完全无视了这个问题,导致我在搜索这个恢复中断的问题时,页面里全都是些如何从中断的状态中恢复过来,真的很无语。
总结
调用线程的interrupt()方法可以向一个阻塞中的线程发出中断请求,其原理就是将线程的中断状态设置为true。
阻塞的线程在收到中断请求的时候,会执行两步操作:清除中断状态,抛出中断异常(InterruptedException)。
这就导致了在一些无法向调用者继续抛出中断异常的情况下,如实现了Runnable接口,必须在run()方法内部进行中断异常的捕获,从而导致了上层调用者可能无法正确获得线程的中断状态,导致没有相应的处理措施,即为中断被屏蔽。
因此,在这种情况下,为了避免任务内部屏蔽了中断请求(注意,屏蔽中断请求并不意味着任务没有响应中断),需要通过在catch块中重新调用任务所在线程的interrupt()方法,恢复到中断状态,来告诉上层调用者,“我是一个已经被中断的线程”。
综上,就是关于《Java并发编程实战》中“恢复中断”的相关理解,欢迎文末留言。
Java并发编程实战————恢复中断相关推荐
- Java并发编程实战————Executor框架与任务执行
引言 本篇博客介绍通过"执行任务"的机制来设计应用程序时需要掌握的一些知识.所有的内容均提炼自<Java并发编程实战>中第六章的内容. 大多数并发应用程序都是围绕&qu ...
- java并发编程实战学习(3)--基础构建模块
转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...
- 【极客时间】《Java并发编程实战》学习笔记
目录: 开篇词 | 你为什么需要学习并发编程? 内容来源:开篇词 | 你为什么需要学习并发编程?-极客时间 例如,Java 里 synchronized.wait()/notify() 相关的知识很琐 ...
- aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- Java并发编程实战_不愧是领军人物!这种等级的“Java并发编程宝典”谁能撰写?...
前言 大家都知道并发编程技术就是在同一个处理器上同时的去处理多个任务,充分的利用到处理器的每个核心,最大化的发挥处理器的峰值性能,这样就可以避免我们因为性能而产生的一些问题. 大厂的核心负载肯定是非常 ...
- 视频教程-Java并发编程实战-Java
Java并发编程实战 2018年以超过十倍的年业绩增长速度,从中高端IT技术在线教育行业中脱颖而出,成为在线教育领域一匹令人瞩目的黑马.咕泡学院以教学培养.职业规划为核心,旨在帮助学员提升技术技能,加 ...
- Java并发编程实战基础概要
文章目录 Java并发编程实战基础概要 开篇 多线程问题有啥难点呢? 为啥要学习并发编程? 并发问题的根源是什么? CPU切换线程执导致的原子性问题是如何发生的? 缓存导致的可见性问题是如何发生的? ...
- Java并发编程实战之互斥锁
文章目录 Java并发编程实战之互斥锁 如何解决原子性问题? 锁模型 Java synchronized 关键字 Java synchronized 关键字 只能解决原子性问题? 如何正确使用Java ...
- 《Java 并发编程实战》--读书笔记
Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...
最新文章
- Verilog有符号数运算
- 一个数三位立方和相加等于本身_【题解信奥】打印水仙花数(粉丝求助)
- 关于restful协议很多人的误解
- linux多线程计算pi,使用蒙特卡洛方法多线程计算pi值
- python散点矩阵图_用python-pandas作图矩阵
- 自然语言处理 —— 2.5 学习词嵌入
- PsotgreSQL
- python多进程用不了_Python多进程相关的坑
- 500并发相当于多少人_linux开发技术之线程池accept处理高并发connect(含源码)
- apache开源项目--thrift
- HNOI2015 接水果
- collections模块 :namedtuple、deque、defaultdict、OrderedDict、ChainMap、Counter
- posix多线程有感--线程高级编程(线程调度以及优先级设置)
- js生成带log的二维码(qrcodejs)
- linux+软盘启动程序,红旗Linux桌面版 4.0软盘启动硬盘安装过程图解 (Red Flag Linux 4.0)...
- 回溯算法之迷宫问题(Maze)
- MTK Android 之MT6577驱动笔记
- 微信公众平台开发3-微信服务器IP接口实例(含源码)
- 双向可控硅实现 插头防插拔火花
- js 解析GET 请求参数