【问题标题】:How to kill a running thread in wait?如何在等待中杀死正在运行的线程?
【发布时间】:2013-10-26 08:02:03
【问题描述】:

当我试图杀死我的 Robber 线程时,有些死了,但有些卡在 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;
}

【问题讨论】:

标签: java multithreading wait


【解决方案1】:

当我试图杀死我的 Robber 线程时,有些会死掉,但有些会卡在 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,因为它看起来可以被多个线程访问。

【讨论】:

    【解决方案2】:

    如@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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多