2013-10-17 46 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(); 
    } 
}