如何在没有任何用处的情况下停止永远运行的线程

时间:2011-06-20 11:54:42

标签: java multithreading

在下面的代码中,我有一个while(true)循环。 考虑到try块中存在一些代码的情况,其中线程应该执行一些约需一分钟的任务,但是由于某些预期的问题,它正在运行。我们可以阻止那个线程吗?


public class thread1 implements Runnable {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        thread1 t1 = new thread1();
        t1.run();

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try{        
                Thread.sleep(10);

            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

6 个答案:

答案 0 :(得分:42)

首先,你没有在这里开始任何线程!您应该创建一个新线程并将名为thread1 Runnable的名称thread1 t1 = new thread1(); final Thread thread = new Thread(t1); thread.start(); 传递给它:

interrupt()

现在,当你真的有一个线程时,有一个内置的功能来中断正在运行的线程,称为...... thread.interrupt();

while(!Thread.currentThread().isInterrupted()){
    try{        
        Thread.sleep(10);
    }
    catch(InterruptedException e){
        Thread.currentThread().interrupt();
        break; //optional, since the while loop conditional should detect the interrupted state
    }
    catch(Exception e){
        e.printStackTrace();
    }

但是,单独设置此标志不会执行任何操作,您必须在正在运行的线程中处理此问题:

while

有两点需要注意:isInterrupted()循环现在将在线程InterruptedException结束。但是如果线程在睡眠期间被中断,那么JVM非常友好,它会通过sleep()抛出AtomicBoolean来通知你。抓住它并打破你的循环。就是这样!


至于其他建议:

  

<强>已过时即可。这种方法本质上是不安全的[...]

  • 添加自己的标志并密切关注它(只记得使用volatilesleep!),但为什么JDK已经为您提供了这样的内置标志呢?额外的好处是中断{{1}},使线程中断更具响应性。

答案 1 :(得分:5)

停止线程的正确方法是interrupt它(stop()已被弃用,可能会产生令人讨厌的副作用):

t1.interrupt()

这会导致InterruptedExceptionThread.sleep()等方法引发Object.wait()

然后只需为此异常添加一个catch块,只需break循环while

编辑:我现在意识到你的无限循环在主线程中运行,你的代码没有创建任何线程,它只是run() ning Runnable。您需要在某个时刻调用Thread.start()来生成新线程。

答案 2 :(得分:2)

在开始执行线程之前创建一个您设置为boolean keepGoing的字段true,并将while (true)替换为while (keepGoing)。在某些时候,您决定在哪里,只需将keepGoing的值更改为false,它就会退出循环。

答案 3 :(得分:2)

停止任意线程的唯一方法是中断。保持对它的引用然后调用中断方法。

答案 4 :(得分:2)

将catch中断移到循环外部。这不需要任何代码行,它只是正确处理中断,即操作被中断。

public void run() {
    try{        
        while(true) {
            Thread.sleep(10);
        }
    } catch(InterruptedException e){
        System.out.println("Thread interrupted"));
    }
}

答案 5 :(得分:1)

我建议使用Thread.interrupt()(如@Bohemian所述)。与使用 ad-hoc 标志相比,它有几个优点:

  • 您无需创建和使用特定于应用程序的API来执行此操作。 (中断可以保证线程安全......)

  • Thread.interrupt()将中断在wait()join中阻塞的线程,或者可能 1 阻塞I / O调用的线程。< / p>

但是,它不是一个神奇的子弹。如果您尝试停止的线程正在执行常规代码,则需要定期检查其interrupted()标志,否则不会停止。这使我们像使用 ad-hoc 标志机制一样处于船上。线程必须合作,否则无法(安全地)停止。

1 - 这是一个阴暗的地方。一方面,有一个InterruptedIOException,其javadoc说“表明I / O操作已被中断”。另一方面,javadoc中没有为各种java.io流类明确提到异常。


确实有些第三方代码可能无法正确处理interrupted标志,因此中断可能会被“吃掉”。但是如果你有源代码,你可以检查一下。对于没有关注 ad-hoc 标志机制的第三方代码,情况并没有太大的不同。


建议使用Thread.stop()。它从根本上说是好消息。有些人声称这对他们有用,但IMO要么处理一个有效的特殊情况......要么他们很幸运。