鉴于此代码:
public class Game implements Runnable {
private volatile boolean stop;
public Game() {
...
}
public void run() {
while(!stop) {
// play game
}
}
public void stopGame() {
stop = true;
}
}
public class Main {
public static void main(String[] args){
Game g = new Game(); // Game class implements Runnable
Thread t = new Thread(g);
t.start();
// do the two method calls below effectively do the same thing?
t.interrupt();
g.stopGame();
}
}
stopGame()是否像使用中断或java.lang.Thread方法杀死线程一样有效地杀死线程? (我不太熟悉你如何使用Thread方法杀死一个线程。)
此外,在stopGame()是杀死线程的最佳方法的情况下,如果他们只能访问Thread实例(如下所示),是否可以调用它:
public static void Main(String[] args){
List<Thread> threads = new ArrayList<Thread>();
threads.add(new Thread(new Game()));
// can you access the Game instance given the Thread instance
// or do you need to hold onto the reference of the Game instance?
threads.get(0).stopGame(); // for example, this won't work.
}
答案 0 :(得分:4)
stopGame()是否像使用中断或java.lang.Thread方法一样有效地停止线程? (我不太熟悉你如何使用Thread方法杀死一个线程。)
停止线程的最佳方法是从run()方法返回。
你的stopGame()调用会在下一次循环中导致这种情况。但是如果该循环包括阻塞调用,那么下一次传递可能会在延迟之后发生 - 或者永远不会发生。
不推荐使用杀死线程的方法,因为它们本质上是不安全的。
Thread.interrupt()
无法保证停止任意线程。它唤醒了一些阻塞调用。在捕获InterruptedException时,Runnable停止是常见的 - 但不是通用的。来自Java tutorial on interrupts:
中断是一个线程的指示,它应该停止它正在做的事情并做其他事情。由程序员决定线程如何响应中断,但线程终止是很常见的。
一种方法是两者设置用户定义的标志并调用Thread.interrupt()。这将中断任何阻塞调用,即使Runnable调用的代码捕获了InterruptedException或清除了中断状态标志,也会工作。
此外,在stopGame()是杀死线程的最佳方法的情况下,如果他们只能访问Thread实例(如下所示),是否可以调用它:
您可以将Thread子类化为持有游戏并在子类中提供一种方法来停止游戏。但是,单独跟踪Runnable实例通常更容易。
答案 1 :(得分:0)
“杀死”线程是一种异常情况。
interrupt()
方法可以完成这项工作,但在这种情况下,您不需要在run()方法的while
条件下使用布尔标志。
这个:
public void run() {
while(!stop) {
// play game
}
}
可能是:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// play game
}
}
但就个人而言,我发现这是一种积极的方式来阻止线程,因为被中断线程的任何阻塞调用都会被唤醒。
当您处于正常退出情况时,您可能会被迫处理这种过早退出,这可能会造成不一致。
使用boolean
标志可以让线程代码负责完成工作,因为它认为它应该不会强制存在阻塞调用。
这并不意味着永远不应该处理InterruptedException
,但我认为对于正常情况(退出用户请求),根据需要使代码更复杂是没有意义的。 BR />
stopGame()是否像使用类似的东西一样有效地杀死线程 中断,还是java.lang.Thread方法来杀死线程?
结束线程的合适方法是允许它终止执行:即方法的run()
完成执行。
使用boolean
条件与while
正如您所做的那样很好:
public void run() {
while(!stop) {
// play game
}
}
另外,在stopGame()是杀死线程的最佳方法的情况下,是 有任何调用它,如果他们只有访问Thread实例 如下所示:
你可以这样做:
Game game = new Game();
game.start();
...
game.stopGame();