博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java--- 使用interrupte中断线程的真正用途
阅读量:7071 次
发布时间:2019-06-28

本文共 1520 字,大约阅读时间需要 5 分钟。

 线程之中,一个线程的生命周期分为:初始、就绪、运行、阻塞以及结束。当然,其中也可以有四种状态,初始、就绪、运行以及结束。

         一般而言,可能有三种原因引起阻塞:等待阻塞、同步阻塞以及其他阻塞(睡眠、jion或者IO阻塞);对于Java而言,等待阻塞是调用wait方法产生的,同步阻塞则是由同步块(synchronized)产生的,睡眠阻塞是由sleep产生的,jion阻塞是由jion方法产生的。

         言归正传,要中断一个Java线程,可调用线程类(Thread)对象的实例方法:interrupte();然而interrupte()方法并不会立即执行中断操作;具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,则根据线程当前的状态进行不同的后续操作。如果,线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true而已;如果线程的当前状态处于阻塞状态,那么在将中断标志设置为true后,还会有如下三种情况之一的操作:

 

  • 如果是wait、sleep以及jion三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException;
  • 如果是java.nio.channels.InterruptibleChannel进行的io操作引起的阻塞,则会对线程抛出一个ClosedByInterruptedException;(待验证)
  • 如果是轮询(java.nio.channels.Selectors)引起的线程阻塞,则立即返回,不会抛出异常。(待验证)
    如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;例如,
一个线程在运行状态中,其中断标志被设置为true,则此后,一旦线程调用了wait、jion、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被清除,重新设置为false。
    通过上面的分析,我们可以总结,
调用线程类的interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。因此,通过interrupted方法真正实现线程的中断原理是:
开发人员根据中断标志的具体值,来决定如何退出线程。
   一个简单的实现方式如下:
[java]   
 
  1. public void run() {  
  2.             try {  
  3.                 while (true){  
  4.                     Thread.sleep(1000l);//阻塞状态,线程被调用了interrupte()方法,清除中断标志,抛出InterruptedException  
  5.                     //dosomething  
  6.                     boolean isIn = this.isInterrupted();  
  7.                     //运行状态,线程被调用了interrupte()方法,中断标志被设置为true  
  8.                     //非阻塞状态中进行中断线程操作  
  9.                     if(isIn) break;//退出循环,中断进程  
  10.                 }  
  11.             }catch (InterruptedException e){
    //阻塞状态中进行中断线程操作  
  12.                 boolean isIn = this.isInterrupted();//退出阻塞状态,且中断标志被清除,重新设置为false,所以此处的isIn为false  
  13.                 return;//退出run方法,中断进程  
  14.             }  
  15.         }  
        分别考虑了阻塞状态中进行中断线程和非阻塞状态中中断线程的处理方式。

 

        最后,说明一下interrupte方法的调用,该方法可在需要中断的线程本身中调用,也可在其他线程中调用需要中断的线程对象的该方法。

转载地址:http://rgzml.baihongyu.com/

你可能感兴趣的文章
LeetCode OJ 之 Ugly Number II (丑数-二)
查看>>
(一)Thymeleaf用法——Thymeleaf简介
查看>>
【Python】 命名空间与LEGB规则
查看>>
巴斯卡三角形
查看>>
产品和团队
查看>>
mysql取差集、交集、并集
查看>>
Tex: The top-level auxiliary file: *.aux I couldn't open style file IEEEtran.bst 解决方法
查看>>
HDU 3080 The plan of city rebuild(prim和kruskal)
查看>>
三层架构—简析
查看>>
利用linux shell自己主动顶贴
查看>>
[转]MVC Razor模板引擎 @RenderBody、@RenderPage、@RenderSection及Html.RenderPartial、Html.RenderAction...
查看>>
bzoj 1860: [Zjoi2006]Mahjong麻将 题解
查看>>
第21章 RTX 低功耗之睡眠模式
查看>>
拉格朗日插值
查看>>
递归函数的写法笔记
查看>>
net 自定义泛型那点事
查看>>
免费「模拟面试」福利反馈连载(20180128期)
查看>>
Redis的并发竞争问题的解决方案总结
查看>>
交叉熵代价函数——当我们用sigmoid函数作为神经元的激活函数时,最好使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢...
查看>>
nxn随机矩阵乘以概率向量依旧是概率向量
查看>>