Thread currentThread=Thread.currentThread(); public void run() { while(!shutdown) { try { System.out.println(currentThread.isAlive()); Thread.interrupted(); System.out.println(currentThread.isAlive()); if(currentThread.isAlive()==false) { shutdown=true; } } catch(Exception e) { currentThread.interrupt(); } } } }); thread.start();
调用stop的替代方法是使用中断向线程发出信号,告知你希望它完成其工作。(这假设你要停止的线程行为良好,如果它在抛出异常后立即通过吃掉它们而忽略了InterruptedException,并且不检查中断状态,那么你将返回使用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()立即抛出,否则你将被困在等待睡眠时间过去。
sleep()
wait()
请注意,不需要单独的布尔标志。
被停止的线程通过检查中断状态并在while循环之外捕获InterruptedExceptions(使用它退出循环)来进行协作。中断是可以将异常用于流控制的一个地方,这就是整个问题的重点。
从技术上讲,在catch块中的当前线程上设置中断是最佳实践,但在此示例中是过大的,因为没有别的东西需要设置中断标志。
关于发布的代码的一些观察:
发布的示例不完整,但是将对当前线程的引用放在实例变量中似乎是个坏主意。它将初始化为正在创建对象的任何线程,而不是初始化为执行run方法的线程。如果同一Runnable实例在多个线程上执行,则该实例变量通常不会反映正确的线程。
检查线程是否处于活动状态始终会导致结果为真(除非currentThread实例变量引用错误的线程时发生错误),Thread#isAlive仅在线程执行完后才为false,只是不会返回false因为它被打断了。
Thread#isAlive
调用Thread#interrupted将导致清除中断标志,并且在这里没有意义,尤其是因为返回值已被丢弃。调用的目的Thread#interrupted是测试中断标志的状态,然后清除它,这是throw事物使用的一种便捷方法InterruptedException。
Thread#interrupted
InterruptedException