Java并发编程的艺术(五)——中断
什么是中断?
在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。因此,Java提供了一种用于停止线程的机制——中断。
- 中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。若要中断一个线程,你需要手动调用该线程的interrupted方法,该方法也仅仅是将线程对象的中断标识设成true;接着你需要自己写代码不断地检测当前线程的标识位;如果为true,表示别的线程要求这条线程中断,此时究竟该做什么需要你自己写代码实现。
- 每个线程对象中都有一个标识,用于表示线程是否被中断;该标识位为true表示中断,为false表示未中断;
- 通过调用线程对象的interrupt方法将该线程的标识位设为true;可以在别的线程中调用,也可以在自己的线程中调用。
中断的相关方法
- public void interrupt() 
 将调用者线程的中断状态设为true。
- public boolean isInterrupted() 
 判断调用者线程的中断状态。
- public static boolean interrupted 
 只能通过Thread.interrupted()调用。
 它会做两步操作:- 返回当前线程的中断状态;
- 将当前线程的中断状态设为false;
 
暂停、继续、停止线程(已过时)
以下三个方法都是通过线程对象去调用。
- suspend() 
 暂停调用者线程,只释放CPU执行权,不释放锁。
 由于在不释放资源的情况下进入睡眠状态,容易产生死锁。因此已过时!
- resume() 
 恢复调用者线程,让他处于就绪状态。
- stop() 
 调用stop后,并不会保证资源被正确地释放,它会使程序处于不正确的状态下。
PS:stop和interrupt的区别?
中断的使用
要使用中断,首先需要在可能会发生中断的线程中不断监听中断状态,一旦发生中断,就执行相应的中断处理代码。 
当需要中断线程时,调用该线程对象的interrupt函数即可。
设置中断监听
Thread t1 = new Thread( new Runnable(){
    public void run(){
        // 若未发生中断,就正常执行任务
        while(!Thread.currentThread.isInterrupted()){
            // 正常任务代码……
        }
        // 中断的处理代码……
        doSomething();
    }
} ).start();正常的任务代码被封装在while循环中,每次执行完一遍任务代码就检查一下中断状态;一旦发生中断,则跳过while循环,直接执行后面的中断处理代码。
触发中断
t1.interrupt();上述代码执行后会将t1对象的中断状态设为true,此时t1线程的正常任务代码执行完成后,进入下一次while循环前Thread.currentThread.isInterrupted()的结果为true,此时退出循环,执行循环后面的中断处理代码。
安全地停止线程
stop函数停止线程过于暴力,它会立即停止线程,不给任何资源释放的余地,下面介绍两种安全停止线程的方法。
循环标记变量
自定义一个共享的boolean类型变量,表示当前线程是否需要中断。
- 中断标识
volatile boolean interrupted = false;- 任务执行函数
Thread t1 = new Thread( new Runnable(){
    public void run(){
        while(!interrupted){
            // 正常任务代码……
        }
        // 中断处理代码……
        // 可以在这里进行资源的释放等操作……
    }
} );- 中断函数
Thread t2 = new Thread( new Runnable(){
    public void run(){
        interrupted = true;
    }
} );循环中断状态
- 中断标识 
 由线程对象提供,无需自己定义。
- 任务执行函数 
Thread t1 = new Thread( new Runnable(){
    public void run(){
        while(!Thread.currentThread.isInterrupted()){
            // 正常任务代码……
        }
        // 中断处理代码……
        // 可以在这里进行资源的释放等操作……
    }
} );- 中断函数
t1.interrupt();总结
上述两种方法本质一样,都是通过循环查看一个共享标记为来判断线程是否需要中断,他们的区别在于:第一种方法的标识位是我们自己设定的,而第二种方法的标识位是Java提供的。除此之外,他们的实现方法是一样的。
上述两种方法之所以较为安全,是因为一条线程发出终止信号后,接收线程并不会立即停止,而是将本次循环的任务执行完,再跳出循环停止线程。此外,程序员又可以在跳出循环后添加额外的代码进行收尾工作。
处理中断
上文都在介绍如何获取中断状态,那么当我们捕获到中断状态后,究竟如何处理呢?
- Java类库中提供的一些可能会发生阻塞的方法都会抛InterruptedException异常,如:BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep。
- 当你在某一条线程中调用这些方法时,这个方法可能会被阻塞很长时间,你可以在别的线程中调用当前线程对象的interrupt方法触发这些函数抛出InterruptedException异常。
- 当一个函数抛出InterruptedException异常时,表示这个方法阻塞的时间太久了,别人不想等它执行结束了。
- 当你的捕获到一个InterruptedException异常后,亦可以处理它,或者向上抛出。
- 抛出时要注意???:当你捕获到InterruptedException异常后,当前线程的中断状态已经被修改为false(表示线程未被中断);此时你若能够处理中断,则不用理会该值;但如果你继续向上抛InterruptedException异常,你需要再次调用interrupt方法,将当前线程的中断状态设为true。
- 注意:绝对不能“吞掉中断”!即捕获了InterruptedException而不作任何处理。这样违背了中断机制的规则,别人想让你线程中断,然而你自己不处理,也不将中断请求告诉调用者,调用者一直以为没有中断请求。
QA
- 为什么catch InterruptedException后会自动清除中断状态?
Java并发编程的艺术(五)——中断的更多相关文章
- Java并发编程的艺术(六)——线程间的通信
		多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java ... 
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
		<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ... 
- Java并发编程的艺术(三)——volatile
		1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行:但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 ... 
- 《Java并发编程的艺术》留给自己以后看的笔记
		<Java并发编程的艺术>这本书特别好,和<深入了解JAVA虚拟机>有一拼,建议做java的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ... 
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
		二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ... 
- 读《Java并发编程的艺术》(一)
		离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督 ... 
- Java并发编程的艺术读书笔记(2)-并发编程模型
		title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ... 
- Java并发编程的艺术读书笔记(1)-并发编程的挑战
		title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- ... 
- java并发编程的艺术(一)---锁的基本属性
		本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ... 
随机推荐
- Vue开源
			Vue开源 - 为移动而生的Vue JS 2组件框架 vonic ★1494 - 快速构建移动端单页应用 eme ★1390 - 优雅的Markdown编辑器 vue-multiselect ★116 ... 
- 【LOJ】#2184. 「SDOI2015」星际战争
			题解 直接二分然后建图跑网络流看看是否合法即可 就是源点向每个激光武器连一条二分到的时间×激光武器每秒攻击值的边 每个激光武器向能攻击的装甲连一条边 每个装甲向汇点连一条装甲值的边 代码 #inclu ... 
- 【AtCoder】ARC090
			C - Candies 前一枚举一个i,求第一行的前i个和第二行从第n个到第i个 代码 #include <bits/stdc++.h> #define fi first #define ... 
- (转载)ACM训练计划,先过一遍基础再按此拼搏吧!!!!
			ACM大量习题题库 ACM大量习题题库 现在网上有许多题库,大多是可以在线评测,所以叫做Online Judge.除了USACO是为IOI准备外,其余几乎全部是大学的ACM竞赛题库. USACO ht ... 
- PAT 1066. Root of AVL Tree (25)
			An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ... 
- React Native Android启动白屏的一种解决方案上
			我们用RN去开发Android应用的时候,我们会发现一个很明显的问题,这个问题就是启动时每次都会有1~3秒的白屏时间,直到项目加载出来 为什么会出现这个问题? RN开发的应用在启动时,首先会将js b ... 
- 样式加载不出来,浏览器控制台报错:Resource interpreted as Stylesheet but transferred with MIME type text/html
			写登录的时候出现的问题,样式时好时坏,浏览器控制台看到的信息是: Uncaught SyntaxError: Unexpected token <Resource interpreted as ... 
- hdu 5772 String problem 最大权闭合子图
			String problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5772 Description This is a simple pro ... 
- 简单分享apache封IP的方法
			1. 在配置文件里设置: 打开httpd.conf编辑:<Directory “/var/www/html”> Options Indexes FollowSymLinks ... 
- OpenVPN搭建中tap与tun的实际使用区别
			tap俗称网桥模式,tun俗称路由模式,tap在二层,tun在三层,在实际应用中,其实以上这些知识概念,我是抄来的,具体的解释可以看以下参考链接. 下面将介绍在实际使用中的区别: 1.tap可以直接使 ... 
