一尘不染

如何杀死线程?不使用stop();

java

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();

阅读 488

收藏
2020-03-04

共1个答案

一尘不染

调用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()立即抛出,否则你将被困在等待睡眠时间过去。

  • 请注意,不需要单独的布尔标志。

  • 被停止的线程通过检查中断状态并在while循环之外捕获InterruptedExceptions(使用它退出循环)来进行协作。中断是可以将异常用于流控制的一个地方,这就是整个问题的重点。

  • 从技术上讲,在catch块中的当前线程上设置中断是最佳实践,但在此示例中是过大的,因为没有别的东西需要设置中断标志。

关于发布的代码的一些观察:

  • 发布的示例不完整,但是将对当前线程的引用放在实例变量中似乎是个坏主意。它将初始化为正在创建对象的任何线程,而不是初始化为执行run方法的线程。如果同一Runnable实例在多个线程上执行,则该实例变量通常不会反映正确的线程。

  • 检查线程是否处于活动状态始终会导致结果为真(除非currentThread实例变量引用错误的线程时发生错误),Thread#isAlive仅在线程执行完后才为false,只是不会返回false因为它被打断了。

  • 调用Thread#interrupted将导致清除中断标志,并且在这里没有意义,尤其是因为返回值已被丢弃。调用的目的Thread#interrupted是测试中断标志的状态,然后清除它,这是throw事物使用的一种便捷方法InterruptedException

2020-03-04