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

gre*_*hma 24 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();
Run Code Online (Sandbox Code Playgroud)

Nat*_*hes 57

调用stop的替代方法是使用interrupt向您希望它完成正在执行的操作的线程发出信号.(这假设您要停止的线程表现良好,如果它在抛出后立即忽略InterruptedExceptions并且不检查中断状态,那么您将返回使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

有些事情要注意:

  • 中断原因sleep()wait()立即投掷,否则你会等待睡眠时间过去.

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

  • 正在停止的线程通过检查中断状态并捕获while循环外的InterruptedExceptions(使用它来退出循环)进行协作.中断是一个可以使用流量控制异常的地方,这就是它的全部要点.

  • 在catch块中设置当前线程的中断在技术上是最佳实践,但对于此示例来说是过度的,因为没有其他任何东西需要设置中断标志.

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

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

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

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


mre*_*mre 14

通常,线程在被中断时终止.那么,为什么不使用本机布尔值?尝试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();
Run Code Online (Sandbox Code Playgroud)

  • +1,人们喜欢自己滚动(布尔),但你必须让它变得不稳定和喧嚣blar ...使用像isInterrupted这样的标准中断策略感觉更优雅:D (2认同)

Raz*_*aze 6

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

class MyRunnable implements Runnable {

    public volatile boolean stopThread = false;

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

}
Run Code Online (Sandbox Code Playgroud)

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