如何终止一个java线程

线程,相比进程更加轻量级,系统开销更小,但过多的线程因系统资源占用多,导致系统性能下降,因此有关线程的管理不得不去做。

在java中如何创建线程呢?相比这样的文章都已多如牛毛,笔者在这里只简单的重述一下。

常见的有两种方式:

1.继承Thread类并重写run方法

2.实现Runnable接口,通过 new Thread(runnableImpl)方式

第2中方式显得更加的灵活,也是经常被采用的方式,第一种方式之所以不灵活主要是因为java中只有单继承,但可以实现多个接口,倘若采用第一种方式,如果你需要继承别的类,此时便无法做到了,起码是无法优雅的做到。。。。


回到正题,怎样终止一个线程呢?

笔者曾经面试被问到过这个问题,当时笔者听到这个问题一脸懵逼,不知如何作答是好,耿直的笔者也没有询问面试官该如何做(哭),之后笔者再网上也是搜了很多关于这个问题的答案,现结合自己的理解,进行整理一下。

如果你的线程仅仅是做一次性的任务,那任务执行完之后线程便会终止,这里讨论的当然不是这种场景下的线程。

Thread 类有提供 stop方法,但此方法已被标记过时,也不推荐使用,因此,如果想通过此方法终止线程的话,那么这个‘梦想’可以破灭了,读者可以完全忘记有这样的方法。

废话不多说了,直接上代码。


第一种方式,通过定义标识变量来终止线程

private boolean done = false;

@Override
public void run() {
   while (done){
      // TODO something
   }
}

这里仅仅是简单的demo,具体情境,具体业务,请读者自行设计和应用,工作远比demo更复杂,更困难。

这种方式简单高效,灵活性极强。


第二种方式,通过线程中断来终止线程

首先笔者需要强调一下,这种方式适合于开发者能控制线程的场景,即能够直接操作Thread对象,如果开发者使用线程池,终止某个线程可能比较困难,甚至根本无法做到

代码如下:

Thread t1 = new Thread(new Runnable() {

   private boolean done = false;

   @Override
   public void run() {
      while (true){

         if(Thread.currentThread().isInterrupted()){
            break;
         }

         // TODO somthing 反复做某件事(假设不会抛异常)
         
         try {
            Thread.sleep(200);
         }catch (InterruptedException ex){

            // 查看线程中断标记状态
            System.out.println(Thread.currentThread().isInterrupted());

            // 重新设置线程中断标记,注意不要与Thread.interrupted()搞混,此方法也会清除线程中断标记
            // 具体参见其注释
            Thread.currentThread().interrupt();
         }
      }
   }
});

t1.start();
try {
   Thread.sleep(1000);

   // 中断线程
   t1.interrupt();
}catch (Exception e){

}

如上所示, catch块的线程中断标记会打印出 false,读者可自行测试一下,具体详情可查看源码注释了解更多。

(如在线程内部没有调用会抛出InterruptedException的方法如sleep方法等(将该异常包装成RuntimeException重新抛出的方法除外),可以不用调用线程对象的 interrupt()方法)

内容到此为止,水平有限,如有错误还请谅解和加以指正。

学无止境,共同进步。









阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页