如何终止线程?不使用 stop();

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

答案 1

调用 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#interruptedThread#interruptedInterruptedException


答案 2

通常,线程在中断时终止。那么,为什么不使用本机布尔值呢?Try isInterrupted()

   Thread t = new Thread(new Runnable(){
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                // do stuff         
            }   
        }});
    t.start();

    // Sleep a second, and then interrupt
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}
    t.interrupt();