中断状态与InterruptedExceptin异常的相互转换

调用interrupt方法后,能够中断掉线程。这里所说中断掉线程,是指下面其中一种结果。java

(1)线程变成“中断状态”对“状态”的反应;设计模式

(2)抛出“异常InterruptedException”对“控制”的反应。多线程

一般会使(1)。只有在线程是sleep、wait、join时会是(2)(这个时候不会变成中断状态)。spa

然而,状态(1)、(2)是能够相互转换的。也就是说,能够把(1)变为(2),也能够把(2)变为(1)。配合程序的须要——大体上就是为了让程序不至于忘记被中断的事实——而加以变化。线程

下面是具体的说明:设计

中断状态 -> InterruptedException异常的转换
code

“若线程是中断状态,就抛出InterruptedException异常”,能够像下面这样写。其中interrupted方法,是java.lang.Thread类的类方法。
it

if(Thread.interrupted()){
    throw new InterruptedException();
}

在花时间的处理前,先加上这个if语句,可提升程序对中断的响应性。能够避免不知道本身已经被中断,还开始进行花时间的处理。io

反却是,这个if语句乍看之下很简单,要彻底了解倒比想象中复杂许多。class

哪一个线程来检查interrupted方法

Thread.interrupted方法,会检查Thread.currentThread()的中断状态。也就是说,上面的if语句不管卸载哪一个类的哪一个方法,都是检查执行if语句的线程的中断状态。

不想清除中断状态的时候

调用Thread.interrupted方法后,线程就不是中断状态了。也就是说,只要调用一次Thread.interrupted方法后,中断状态就会被清除。

若是不想清除中断状态,而要检查如今线程是否被中断,要使用isInterrupted实例方法。调用方式以下:

if(Thread.currentThread.isInterrupted()){
    //若为中断中断时须要进行的处理(中断状态不会清除)
}

InterruptedException异常 -> 转换为中断状态

想要让线程只有在指定的时间才中止时,可使用Thread.sleep方法。由于Thread.sleep会抛出InterruptedException异常,因此可能咱们须要常常会这样写:

try {
    Thread.sleep(1000);
} catch (InterruptedException e){
}

不过,这样写的话,抛出的InterruptedException异常会被忽略。当sleep被其余线程interrupt时,“被中断”这个事实会消失。

若当咱们不但愿被中断这个事实消失时,就像下面这样,本身再从新中断本身一次。

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread.interrupt();
}

这样能够将收到的InterruptedException异常转换为中断状态的形式。

InterruptedException异常 -> 转换为InterruptedException异常

收到的InterruptedException异常,也能够不立刻抛出来,而留下来晚点再抛。以下:

  InterruptedException savedException = null;
  ...
  
  try {
      Thread.sleep(1000);
  } catch (InterruptedException e) {
      savedException = e;
  }
  ...
  if (savedException != null){
      throw savedException;
  }

在这里,先将收到的InterruptedException存在变量savedException里,留到后面才throw出去。

内容来源于《Java多线程设计模式》一书,方便之后查看。

相关文章
相关标签/搜索