4

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;
}
4

2 に答える 2

1

@Grayの回答で示されているように、スレッドを中断することはそれを行う1つの方法ですが、Robberを中断するのではなく、Robberを「殺す」ときに待機中のスレッドをウェイクアップする方がクリーンな場合があります。

以下のこの例では、「強盗タスク」(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();
    }
}
于 2013-10-17T18:03:31.370 に答える