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

ran*_*psp 23 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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*icz 42

首先,你没有在这里开始任何线程!您应该创建一个新线程,并将令人困惑的名称传递thread1 Runnable给它:

thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();
Run Code Online (Sandbox Code Playgroud)

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

thread.interrupt();
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
Run Code Online (Sandbox Code Playgroud)

有两点需要注意:while循环现在会在线程结束时结束isInterrupted().但是如果线程在睡眠期间被中断,那么JVM是如此善良,它会通过抛出InterruptedException来通知你sleep().抓住它并打破你的循环.而已!


至于其他建议:

不推荐.这种方法本质上是不安全的[...]

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


Cos*_*atu 5

停止线程的正确方法是interrupt它(stop()不推荐使用并且可能有令人讨厌的副作用):

t1.interrupt()
Run Code Online (Sandbox Code Playgroud)

这将导致InterruptedExceptionThread.sleep()或等方法抛出Object.wait().

然后只需为此异常添加一个catch块,并且只是breakwhile循环之外.

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