如何在等待中杀死正在运行的线程?

时间:2013-10-17 17:27:49

标签: java multithreading wait

当我试图杀死我的强盗线程时,有些人会死掉,但是有些人会陷入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;
}

2 个答案:

答案 0 :(得分:6)

  

当我试图杀死我的强盗线程时,有些人会死掉,但有些人会陷入wait()阻止,这将是一种杀死所有线程的更好方法,

“杀死”线程的正确方法是使用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()) {

顺便说一句,alive应为volatile,因为它似乎可以被多个线程访问。

答案 1 :(得分: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();
    }
}