我怎么能杀死一个线程?不使用stop();

时间:2011-05-06 17:53:12

标签: java multithreading interrupted-exception interruption

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

3 个答案:

答案 0 :(得分:56)

调用stop的替代方法是使用interrupt向您希望它完成正在执行的操作的线程发出信号。 (这假设您要停止的线程表现良好,如果它在抛出后立即通过吃掉它们而忽略InterruptedExceptions并且不检查中断状态,那么您将返回使用stop()。)

这是我编写的一些代码,作为线程问题here的答案,它是线程中断如何工作的一个例子:

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实例,则实例变量在大多数情况下不会反映正确的线程。

  • 检查线程是否处于活动状态必然总是导致为true(除非currentThread实例变量引用错误的线程时出现错误),Thread#isAlive仅在线程后为false已经完成执行,它不会因为被中断而返回false。

  • 调用Thread#interrupted将导致清除中断标志,这里没有任何意义,特别是因为丢弃了返回值。调用Thread#interrupted的目的是测试中断标志的状态然后清除它,这是抛出InterruptedException的东西使用的一种方便方法。

答案 1 :(得分:14)

通常,线程在中断时终止。那么,为什么不使用 native boolean ?试试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();

答案 2 :(得分:6)

这样做的好方法是使用布尔标志来表示线程。

class MyRunnable implements Runnable {

    public volatile boolean stopThread = false;

    public void run() {
            while(!stopThread) {
                    // Thread code here
            }
    }

}

创建一个名为myrunnable的MyRunnable实例,将其包装在新的Thread实例中并启动实例。如果要标记要停止的线程,请设置myrunnable.stopThread = true。这样,它就不会停留在某个东西的中间,只有我们期望它停止的地方。