2013-10-17 63 views
3

當我試圖殺死我的強盜線程時,有些死亡,但有些卡在wait()塊中,那麼將會有更好的方法殺死所有線程,或者我如何獲得被阻塞的線程被殺死?如何殺死正在運行的線程?

private int robberId; 
private static int robberGlobalId=0; 
private TreasureChest chest; 
private boolean alive = true; 

public Robber(TreasureChest chest) { 
    robberId = robberGlobalId; 
    robberGlobalId++; 

    this.chest = chest; 
} 

public void run() { 
    while (alive) { 
     try { 
      synchronized(chest){ 
       robCoin(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    System.out.println("Robber " +robberId +" just died"); 
} 

public void robCoin() throws InterruptedException { 
    if (chest.getTreasureAmount() <= 0) { 
     chest.wait(); 
    } else { 
     chest.removeCoin(); 
    } 
    Thread.sleep(50); 
} 

public void killRobber() { 
    alive = false; 
} 
+0

http://arashmd.blogspot.com/2013/06/java-threading.html#shuttr – 2013-10-17 17:49:25

回答

6

當我試圖殺死我的強盜線程,一些死,但有些人會停留在等待()塊,這將是一個更好的方式來殺死所有的線程,

「殺死」線程的正確方法是用thread.interrupt()來中斷它。如果該線程在wait(...)呼叫中被阻止,則會立即拋出InterruptedException。當你捕捉InterruptedException時,立即重新中斷線程以保留中斷標誌是一個好主意,因爲拋出異常時,中斷位被清除。

try { 
    ...wait(); 
} catch (InterruptedException ie) { 
    Thread.currentThread().interrupt(); 
    // handle the interrupt 
    return; 
} 

由於不是所有的方法都拋出InterruptedException,你也可以檢查,以確保該線程已經中斷的東西,如下列:

if (Thread.currentThread().isInterrupted()) { 
    // stop processing 
    return; 
} 

或者在你的情況是這樣的:

while (alive && !Thread.currentThread().isInterrupted()) { 

Btw,alive應該是volatile,因爲它看起來被多個線程訪問。

1

中斷線程是實現它的一種方法,如@Gray的答案所示,但是當你「殺死」強盜而不是中斷它們時,喚醒等待線程可能會更清晰。

在下面的示例中,「強盜任務」(由run()方法執行)將等待強盜活着並且胸部爲空(小於或等於0)。如果killRobber()被稱爲等待線程被喚醒並優雅地退出run()(活着將是false)。

public void run() { 
    try{ 
     synchronized(chest){ 
      while (chest.getTreasureAmount() <= 0 && alive) { 
       chest.wait(); 
      } 
      if(alive){ 
       chest.removeCoin(); 
      } 
     } 
    }catch (InterruptedException ie){ 
     /* Thread interrupted do something appropriate, 
      which may be to do nothing */ 
    } 
} 

public void killRobber() { 
    synchronized(chest){ 
     alive = false; 
     chest.notifyAll(); 
    } 
}