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