中斷狀態與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多線程設計模式》一書,方便之後查看。

相關文章
相關標籤/搜索