调用 stop 的替代方法是使用中断向线程发出信号,表明您希望它完成它正在执行的操作。(这假设您要停止的线程表现良好,如果它在抛出中断的异常后立即吃掉它们来忽略它们,并且不检查中断状态,那么您将返回使用stop()。
以下是我编写的一些代码,作为对此处线程问题的答案,这是线程中断如何工作的一个示例:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
需要注意的一些事项:
打断原因并立即投掷,否则你被困在等待睡眠时间过去。sleep()
wait()
请注意,不需要单独的布尔标志。
正在停止的线程通过检查中断状态并在 while 循环外部捕获中断异常(使用它退出循环)来进行协作。中断是可以使用异常进行流控制的一个地方,这就是它的全部意义。
在 catch 块中的当前线程上设置中断在技术上是最佳做法,但对于此示例来说,这是过分的,因为没有其他需要设置中断标志的内容。
关于发布代码的一些观察结果:
发布的示例不完整,但是在实例变量中放置对当前线程的引用似乎是一个坏主意。它将初始化为创建对象的任何线程,而不是执行 run 方法的线程。如果同一 Runnable 实例在多个线程上执行,则实例变量在大多数时间不会反映正确的线程。
检查线程是否处于活动状态必然总是会导致 true(除非存在当前线程实例变量引用错误线程的错误),只有在线程完成执行后才为 false,它不会仅仅因为它被中断而返回 false。Thread#isAlive
调用将导致清除中断标志,在这里没有意义,特别是因为返回值被丢弃。调用的要点是测试中断标志的状态,然后清除它,这是抛出的东西使用的方便方法。Thread#interrupted
Thread#interrupted
InterruptedException