Java并发——线程中断学习
1. 使用interrupt()中断线程
当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。如下代码所示:
public class SleepInterrupt implements Runnable {
@Override
public void run() {
try {
System.out.println("子线程开始执行");
Thread.sleep(20000);
System.out.println("子线程继续执行");
} catch (InterruptedException e) {
System.out.println("子线程遇到中断异常");
//处理完中断异常后,返回到run()方法入口
//如果没有return,线程不会实际被中断,它会继续打印下面的信息
return;
}
System.out.println("子线程执行结束");
}
public static void main(String[] args) {
SleepInterrupt si = new SleepInterrupt();
Thread t = new Thread(si);
t.start();
//主线程休眠2秒,从而确保刚才启动的线程有机会执行一段时间
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程对子线程执行中断操作");
//中断线程t
t.interrupt();
System.out.println("主线程结束执行");
}
}
主线程启动新线程后,自身休眠2秒钟,允许新线程获得运行时间。新线程打印信息“子线程开始执行”后,继而休眠20秒钟,大约2秒钟后,main线程通知新线程中断,那么新线程的20秒的休眠将被打断并抛出InterruptException异常,执行跳转到catch块,打印出“子线程遇到中断异常”信息后结束。
请注意:由于不确定的线程规划,上图运行结果的后两行可能顺序相反,这取决于主线程和新线程哪个先消亡。但前两行信息的顺序必定如上图所示。
另外,如果将catch块中的return语句注释掉,则线程在抛出异常后会继续往下执行,而不会被中断,从而会打印出”子线程执行结束”信息。
2. 待决中断
在上面的例子中,sleep()方法的实现检查到休眠线程被中断,它会相当友好地终止线程,并抛出InterruptedException异常。另外一种情况,如果线程在调用sleep()方法前被中断,那么该中断称为待决中断,它会在刚调用sleep()方法时,立即抛出InterruptedException异常。
public class PendingInterrupt extends Object {
public static void main(String[] args) {
//在main线程中中断当前线程(即main线程)
Thread.currentThread().interrupt();
//获取当前时间
long startTime = System.currentTimeMillis();
try {
Thread.sleep(2000);
System.out.println("没有被中断");
} catch (InterruptedException e) {
System.out.println("被中断");
}
//计算中间代码执行的时间
System.out.println("执行耗时=" + (System.currentTimeMillis() - startTime));
}
}
这种模式下,main线程中断它自身。除了将中断标志(它是Thread的内部标志)设置为true外,没有其他任何影响。线程被中断了,但main线程仍然运行,main线程继续监视实时时钟并进入try块,一旦调用sleep()方法就会注意到待决中断的存在,并抛出InterruptException。于是执行跳转到catch块,并打印出线程被中断的信息。最后,计算并打印出时间差。最终输出的时间差距应该远小于2000。
3. 使用isInterrupted()方法判断中断状态
可以在Thread对象上调用isInterrupted()方法来检查任何线程的中断状态。
这里需要注意:线程一旦被中断isInterrupted()方法便会返回true,而一旦sleep()方法抛出异常,它将清空中断标志,此时isInterrupted()方法将返回false。下面的代码演示了isInterrupted()方法的使用:
public class InterruptCheck{
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println("Point A: t.isInterrupted()=" + t.isInterrupted());
//待决中断,中断自身
t.interrupt();
System.out.println("Point B: t.isInterrupted()=" + t.isInterrupted());
System.out.println("Point C: t.isInterrupted()=" + t.isInterrupted());
try {
Thread.sleep(2000);
System.out.println("was NOT interrupted");
} catch (InterruptedException e) {
System.out.println("was interrupted");
}
//跑出异常后,会清除中断标志,这里会返回false
System.out.println("Point D: t.isInterrupted()=" + t.isInterrupted());
}
}
4. 使用Thread.interrupted()方法判断中断状态
可以使用Thread.interrupted()方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么这个方法返回true。与isInterrupted()不同,它将自动重置中断状态为false,第二次调用Thread.interrupted()方法,总是返回false,除非中断了线程。
如下代码演示了Thread.interrupted()方法的使用:
public class InterruptReset{
public static void main(String[] args) {
System.out.println(
"Point X: Thread.interrupted()=" + Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println(
"Point Y: Thread.interrupted()=" + Thread.interrupted());
System.out.println(
"Point Z: Thread.interrupted()=" + Thread.interrupted());
}
}
Java并发——线程中断学习的更多相关文章
- 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 运行 (调用 ...
- 从JDK源码角度看java并发线程的中断
线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...
- Java并发编程深入学习
上周的面试中,被问及了几个并发开发的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,该书内容主要是对ifev ...
- Java并发——线程介绍
前言: 互联网时代已经发展到了现在.从以前只考虑小流量到现在不得不去考虑高并发的问题.扯到了高并发的问题就要扯到线程的问题.你是否问过自己,你真正了解线程吗?还是你只知道一些其他博客里写的使用方法.下 ...
- Java并发编程快速学习
上周的面试中,被问及了几个关于Java并发编程的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,学习后的体会 ...
- Java并发——线程间的等待与通知
前言: 前面讲完了一些并发编程的原理,现在我们要来学习的是线程之间的协作.通俗来说就是,当前线程在某个条件下需要等待,不需要使用太多系统资源.在某个条件下我们需要去唤醒它,分配给它一定的系统资源,让它 ...
随机推荐
- Python 基于python编写一些算法程序等
基于python编写一些算法程序等 by:授客 QQ:1033553122 QQ群:7156436 没特意去研究,只是这对群友在QQ群里(7156436)提出的一些小程序实现.编程题,算法.问题等,本 ...
- system.transfer.list版本进化
从android5.0开始之后,recovery升级包中不再升级system.img,而是升级system.new.dat+system.transfer.list的这种文件组合,经过android版 ...
- mysql中的utf8mb4、utf8mb4_unicode_ci、utf8mb4_general_ci
1.utf8与utf8mb4(utf8 most bytes 4) MySQL 5.5.3之后增加了utfmb4字符编码 支持BMP(Basic Multilingual Plane,基本多文种平面) ...
- [20171113]修改表结构删除列相关问题4.txt
[20171113]修改表结构删除列相关问题4.txt --//连续写了3篇修改表结构删除列的相关问题,链接如下: http://blog.itpub.net/267265/viewspace-214 ...
- [20170904]11Gr2 查询光标为什么不共享脚本.txt
[20170904]11Gr2 查询光标为什么不共享脚本.txt --//参考链接下面的注解脚本:https://carlos-sierra.net/2017/09/01/poors-man-scri ...
- c#事务处理(sqlTransaction)
事务: /// <summary> /// 删除考勤 /// </summary> /// <param name="dto">Id</p ...
- orcale 把日期当做查询条件
根据日期查询范围 精确到天 select * from table where to_char( time,'yyyy mm dd ' ) <= '2000 01 01' select * ...
- git命令行clone指定分支、更新、冲突解决、提交代码步骤
clone指定分支 : git init 初始化仓库 git clone -b 分支名 git@192.168.3.166:xxxx/xxxx.git 克隆指定分支 更新 :git status ...
- java.lang.RuntimeException: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.demoDao.getXXX;
java.lang.RuntimeException: org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...
- 【HTTP缓存】浏览器缓存理论知识
时间:2016-12-12 17:51:30 作者: zhongxia 零.前言 这里主要写的是理论,具体实践的比较少,后期写一个实践教程,内容基本都是从参考文章里面抄过来的[看完文章,顺便写做下笔记 ...