Java线程Thread之interrupt中断的示例分析

这篇文章将为大家详细讲解有关Java线程Thread之interrupt中断的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

成都创新互联公司长期为数千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为海盐企业提供专业的做网站、成都网站设计,海盐网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。

中断线程

线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。

判断线程是否被中断

判断某个线程是否已被发送过中断请求,请使用Thread.currentThread().isInterrupted()方法(因为它将线程中断标示位设置为true后,不会立刻清除中断标示位,即不会将中断标设置为false),而不要使用thread.interrupted()(该方法调用后会将中断标示位清除,即重新设置为false)方法来判断,下面是线程在循环中时的中断方式:

while(!Thread.currentThread().isInterrupted() && more work to do){
 do more work
}

interrupt之中断状态标记

interrupt中断机制中有如下方法:

  1. Thread.interrupt(),设置当前中断标记为true(类似属性的set方法)

  2. Thread.isInterrupted(),检测当前的中断标记(类似属性的get方法)

  3. Thread.interrupted(),检测当前的中断标记,然后重置中断标记为false(类似属性的get方法+set方法)

因此interrupt中断机制并不是真正的将当前线程中断,而是一个中断标记的变化。我们先用例子来测试一下。

public class InterruptTest {
 //这里用来打印消耗的时间
 private static long time = 0;
 private static void resetTime(){
 time = System.currentTimeMillis();
 }
 private static void printContent(String content){
 System.out.println(content + "  时间:" + (System.currentTimeMillis() - time));
 }

 public static void main(String[] args) {
 test1();
 }

 private static void test1(){
 Thread1 thread1 = new Thread1();
 thread1.start();
 //延时3秒后interrupt中断
 try {
  Thread.sleep(3000);
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 thread1.interrupt();
 printContent("执行中断");
 }

 private static class Thread1 extends Thread{
 @Override public void run() {
  resetTime();
  int num = 0;
  while (true){
  if(isInterrupted()){
   printContent("当前线程 isInterrupted");
   break;
  }
  num++;
  if(num % 100 == 0){
   printContent("num : " + num);
  }
  }
 }
 }
}

以上代码是开启一个Thread1线程,在Thread1线程的while循环中不断对num加1,每到100的倍数打印一次(防止打印太快)。然后主线程在sleep了3000毫秒后,调用Thread1线程的interrupt方法。那么我们看看输出结果:

Java线程Thread之interrupt中断的示例分析

intterupt中断

可以看到,在耗时3000毫秒左右,也就是主线程sleep之后执行thread1.interrupt();后,Thread1线程停止了,而Thread1线程的停止是因为while循环中的isInterrupted方法返回了true,所以break退出了while循环,也就是说interrupt和isInterrupted在这里起到的作用就相当于setXX和getXX的作用,维护着一个boolean变量。

interrupt之中断异常处理

当然interrupt机制并不仅仅是一个中断状态位的变化和检测,它还可以进行中断异常的处理。我们知道Thread.sleep()方法需要捕获中断异常,那接下来我们往其中添加一个sleep延时试试

 while (true){
 if(isInterrupted()){
  printContent("当前线程 isInterrupted");
  break;
 }
 num++; 
 //sleep一下
 try {
  Thread.sleep(1);
 } catch (InterruptedException e) {
  e.printStackTrace();
 }

 if(num % 100 == 0){
  printContent("num : " + num);
 }
 }

我们再看看输出结果:

Java线程Thread之interrupt中断的示例分析

intterupt中断

这里我们会发现,sleep睡眠之后,输出的num值明显小了好多(没睡眠时num都达到10亿的大小了,看来CPU执行简单运算还是非常快的),哈哈,不过这不是重点,重点是是看到输出了一个异常,还有就是输出异常后,isInterrupted输出返回false,Thread1线程又继续执行下去了,并没有退出while循环。那么这是为什么呢?我们只是加了一个sleep睡眠而已。

如果Thread1线程中有执行需要捕获InterruptedException异常的操作,比如Thread的sleep,join方法,Object的wait,Condition的await等,它是强制需要捕获InterruptedException异常的,那么当thread1.interrupt方法调用之后,它会给thread1线程抛出一个InterruptedException异常,那么在while循环中,就能捕获到这个异常然后这个异常抛出之后,又会马上将线程中断标识重置为false,因此在下次的while循环中判断isInterrupted时,它是false,也就不会break,然后while循环会一直执行下去。

因此interrupt()方法会根据thread线程中的run方法里是否有必须捕获InterruptedException异常的代码,而做出不同操作:

  1. 如果没有必须捕获InterruptedException异常的代码(比如Thread.sleep()),则isInterrupted()会返回true,此时可以在isInterrupted的判断中处理中断变化。

  2. 如果有必须捕获InterruptedException异常的代码(比如Thread.sleep()),则会抛出InterruptedException异常,并进行捕获,同时重置isInterrupted为false,此时得在异常捕获中处理中断变化。

interrupt的应用场景

通常interrupt适用于在线程执行中的循环标记判断,例如

while(!isInterrupted()){
 ...
}

但是如果在本次循环中出现阻塞了,那么线程就无法判断下次的isInterrupted标记,那么即便调用了interrupt()方法也无法退出循环,也就无法退出线程。例如

while(!isInterrupted()){
 ... 
 while(true){
  //线程卡在这里了,则无法响应interrupte机制了
 }
}

这样的话,interrupt就没辙了,线程会一直执行下去,不会被中断停止。

关于“Java线程Thread之interrupt中断的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

标题名称:Java线程Thread之interrupt中断的示例分析
本文路径:https://www.cdcxhl.com/article34/pjjjpe.html

成都网站建设公司_创新互联,为您提供企业网站制作搜索引擎优化响应式网站网站设计虚拟主机服务器托管

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

搜索引擎优化