如何杀死一个线程?

1.简介

在这篇短文中,我们将讲述一下java中如果结束一个线程-事实上,这并没有想象中的那么简单,因为 Thread.stop()方法已经被废弃啦。

根据Oracle的解释,stop()方法可以导致被监视对象遭受破坏。

2.使用一个Flag

我们先创建一个类并在其中创建启动一个线程,这个任务它自己不会结束,因此,我们需要有一个办法去结束这个线程。针对这种情况,我们将使用一个原子flag(atomic flag):

public   class    ControlSubThread   implements   Runnable {

    private Thread  worker;

    private  final  AtomicBoolean running = newAtomicBoolean(false);

    private int  interval;

    public     ControlSubThread(intsleepInterval) {

        interval = sleepInterval;

    }

    public   void   start() {

        worker = newThread(this);

        worker.start();

    }

    public void  stop() {

        running.set(false);

    }

    public void  run() {

        running.set(true);

        while(running.get()) {

            try{

                Thread.sleep(interval);

            } catch(InterruptedException e){

                Thread.currentThread().interrupt();

                System.out.println(

                  "Thread was interrupted, Failed to complete operation");

            }

            // do something here

         }

    }

}

相比较于用一个while循环来计算一个常量值,我们现在使用一个原子性的布尔值AtomicBoolean 并且我们可以通过设置它为true还是false来启动和结束一个线程的执行。

3.中断一个线程

当sleep()方法被设置了一个较长时间的睡眠时间,或者我们正在等待一个可能永远不能被释放的锁时,会发生什么事情 ?我们就面临着长时间阻塞或永远不能结束的风险。

针对这些情况,我们创建了interrupt()方法,同时我们会在该类上增加一些方法并且新增一个flag:

public   class      ControlSubThread implements   Runnable {

    private    Thread    worker;

    private    AtomicBoolean running = newAtomicBoolean(false);

    private    intinterval;

    // ...

    public   void   interrupt() {

        running.set(false);

        worker.interrupt();

    }

    boolean    isRunning() {

        returnrunning.get();

    }

    boolean    isStopped() {

        returnstopped.get();

    }

    public  void  run() {

        running.set(true);

        while(running.get()) {

            try{

                Thread.sleep(interval);

            } catch(InterruptedException e){

                Thread.currentThread().interrupt();

                System.out.println(

                  "Thread was interrupted, Failed to complete operation");

            }

            // do something

        }

    }

}

我们已经添加了一个interrupt()方法,该方法会把我们的runningflag 设置为false并且调用worker线程的interrupt()方法。如果在调用时,该线程正在睡眠中,那么sleep()方法将退出并且抛出一个InterruptedException,就像其他阻塞调用一样。它会把该线程带回到循环中而且它将会退出,因为此时running的值为false。


4.结论

在这篇文章中,我们看到了如何使用原子变量以及interrupt()方法去干干净净地关闭一个线程。这肯定比调用已经废弃的stop()方法要好的多。因为stop()方法可能面临着阻塞以及内存损坏的风险。

你可能感兴趣的:(如何杀死一个线程?)