Java并发——线程中断学习

1. 使用interrupt()中断线程

当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。如下代码所示:

public class SleepInterrupt implements Runnable {@Overridepublic 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("主线程对子线程执行中断操作");//中断线程tt.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");  }//跑出异常后,会清除中断标志,这里会返回falseSystem.out.println("Point D: t.isInterrupted()=" + t.isInterrupted());}}
这里写图片描述

4.  使用Thread.interrupted()方法判断中断状态

可以使用Thread.interrupted()方法来检查当前线程的中断状态(并隐式重置为false)。又由于它是静态方法,因此不能在特定的线程上使用,而只能报告调用它的线程的中断状态,如果线程被中断,而且中断状态尚不清楚,那么这个方法返回trueisInterrupted()不同,它将自动重置中断状态为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());  }}
这里写图片描述

转载于:https://www.cnblogs.com/qitian1/p/6461439.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python etree创建xml_Python构建XML树结构的实例教程

这篇文章主要介绍了Python构建XML树结构的方法,结合实例形式分析了Python创建与打印xml数结构的实现步骤与相关操作技巧,需要的朋友可以参考下本文实例讲述了Python构建XML树结构的方法。分享给大家供大家参考,具体如下:1.构建XML元素#encodingutf-8from…

分布式服务框架原理(一)设计和实现

分布式服务框架设计 分布式服务框架一般可以分为以下几个部分, (1)RPC基础层: 包括底层通信框架,如NIO框架、通信协议,序列化和反序列化协议,以及在这几部分上的封装,屏蔽底层通信细…

or函数 java_Java OptionalInt orElseGet()用法及代码示例

orElseGet(java.util.function.IntSupplier)方法可帮助我们获取此OptionalInt对象中的值。如果此OptionalInt中不存在值,则此方法返回提供函数产生的结果,并作为参数传递用法:public int orElseGet(IntSupplier supplier)参数:此方法接受提供…

ADO.NET高级应用

ADO.NET事务处理(4个步骤) 1.调用SqlConnection对象的BeginTransaction()方法,创建一个SqlTransaction对象,标志事务开始。 2.将创建的SqlTransaction对象分配给要执行的SqlCommand的Transaction属性。 3.调用相应的方法执行SqlCommand命令。 4.调用SqlT…

php日常收获

php1、sprintf 用法(晚上写成blog w3cschool可查)2、使用thinkphp getfield 方法时只查询一个字段默认返回第一条数据,如果想要返回数组需要写成:$this->getField(id,true); // 获取id数组3、数据分页时配合limit(x…

java dfs算法蓝桥杯题_【蓝桥杯省赛JavaB组真题详解】四平方和(2016)_疼疼蛇的博客-CSDN博客...

原文作者:疼疼蛇原文标题:【蓝桥杯省赛JavaB组真题详解】四平方和(2016)发布时间:2021-02-26 15:00:01题目描述四平方和四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。如果把0包括进…

Spring JdbcTemplate查询实例

这里有几个例子向您展示如何使用JdbcTemplate的query()方法来查询或从数据库提取数据。整个项目的目录结构如下:1.查询单行数据这里有两种方法来查询或从数据库中提取单行记录,并将其转换成一个模型类。1.1 自定义RowMapper 在一般情况下,它总…

访问php文件显示500错误,nginx 访问.php文件正常,访问.html文件500错误

#php解析需要配置以下参数181 location ~ \.php|\.html$ {把下面的一行修改为上面的,重启nginx服务器。182 #location ~ \.php$ {183 #root /var/www;184 fastcgi_pass 127.0.0.1:9000;185 fastcgi_index index.php;186 #fastcgi_param SCRIPT_FILENAME /scripts$fa…

下面哪个进制能表述 13*16=244是正确的?)[中国台湾某计算机硬件公司V2010年5月面试题]...

A.5B.7C.9D.11解析:13如果是一个十进制的话,它可以用131*1013*100来表示。现在我们不知道13是几进制,那我们姑且称其X进制。X进制下的13转化为十进制可以用131*X13*X0;表示;X进制下的…

AngularJS中页面传参方法

1、基于ui-router的页面跳转传参 (1) 用ui-router定义路由,比如有两个页面,一个页面(producers.html)放置了多个producers,点击其中一个目标,页面跳转到对应的producer页面,同时将producerId这个参数传过去。 .state(p…

php注册树模式,PHP设计模式之详记注册树模式

一、什么是注册树模式注册树模式又叫注册模式、注册器模式。注册树模式是将经常使用到的对象实例挂到一颗全局的树上,需要使用时从数树上取出即可。举个栗子:有一个空的工具箱。需要维修东西,因此买了扳手和螺丝刀等工具,将它们放…

php和数据库的接口,php数据库接口

三套方案 mysql mysqli pdo1、mysql扩展库 效率不怎么高的数据库2、mysqli扩展库3、pdo 可以操作任何一种数据库mysql扩展库和mysqli的扩展库,扩展库就是操作数据库的一个集合mysql数据库是用于存放数据的可以查看php可以使用的扩展库 phpinfo();创建新表…

saltstack之混合匹配

需要-C参数: salt -C ## 使用grains属性来匹配 [roothadoop0 pillar]# salt -C Gos:Ubuntu test.ping uadoop1:True ## 使用Minion ID的正则表达式来匹配 [roothadoop0 pillar]# salt -C Euadoop\d test.ping uadoop2:True uadoop3:True uadoop1:True ## 使用gr…

java自定义 filter,HBase自定义Filter

必需要提前说明下:不建议使用自定义的Filter。所有的Filter都是在服务端生效:就是说需要将自定义的Filter封装为jar,上传到HBase的类路径下,并重启HBase使之生效。对于生产环境的HBase来说,重启通常是不能接受的。Filt…

Mybatis学习总结(二)——Mapper代理开发

一、概要 1、原始DAO开发中存在的问题:(1)DAO实现方法体中存在很多过程性代码。(2)调用SqlSession的方法(select/insert/update)需要指定Statement的id,存在硬编码,不利于代码维护。 2、Mapper动态代理方法…

mac wordpress php7,Mac 下基于 wordpress 搭建个人博客系统

一、前言这里说的是自己从 wordpress 源码开始搭建一个个人博客系统。当然,很多云端已经直接提供了在线安装的方式,这个就不在本文的讨论范围之内了。二、关于 wordpresswordpress是一款个人博客系统,并逐步演化成一款内容管理系统软件&#…

TypeError: db.addUser is not a function : @(shell):1:1 ——mongoDB创建新用户名密码的方法...

不多说,旧版本使用 db.addUser("root","root") 新版本使用这句会出现这个错误提示 TypeError: db.addUser is not a function : (shell):1:1 新版本用的是 db.createUser({user: "test",pwd: "test",roles: [ { role: &quo…

php多人访问抽奖倒计时一致,Javascript和PHP倒计时器为每个人显示相同的计时器...

我有生成倒计时器所需的脚本,该计时器有一个启动和恢复按钮.我试图做的是在一个控制另一页上的计时器的页面上有启动,停止和重置按钮.因此,如果用户X访问page.html,他们将看到一个0的计时器.Admin X访问admin.html,他们看到计时器为0,但他们也有一个启动,停止和重置按钮.当管理…

将list中的元素按照属性分类成树状的map

技术交流群&#xff1a; 233513714public LinkedHashMap<String, List<TPhoneModel>> queryPhoneList(List<TPhoneModel> list) {LinkedHashMap<String, List<TPhoneModel>> map new LinkedHashMap<>();for (TPhoneModel li : list) {  …

java能传地址吗,详解java的值传递、地址传递、引用传递

一直来觉得对值传递和地址传递了解的很清楚&#xff0c;刚才在开源中国上看到一篇帖子介绍了java中的值传递和地址传递&#xff0c;看完后感受颇深。下边总结下以便更容易理解。按照以前的理解&#xff0c;java中基本数据类型是值传递&#xff0c;对象是地址(引用)传递。给大家…