线程,相比进程更加轻量级,系统开销更小,但过多的线程因系统资源占用多,导致系统性能下降,因此有关线程的管理不得不去做。
在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()方法)
内容到此为止,水平有限,如有错误还请谅解和加以指正。
学无止境,共同进步。