如何正确的停止一个线程
2018-09-01 05:42:45来源:博客园 阅读 ()
================================题外话=================================
复习多线程的知识,偶然看到一道题:如何正确的停止一个线程?我第一反应是使用stop()方法停止,操作以后发现stop已经被废弃了。
经过查找资料,发现是使用interrupt()进行中断标记然后在进行停止,特此写这篇随笔记录一下。
------------------------------------------------------------------------------------------------------------------------------------
stop()、suspend()的缺点
1.会导致一些清理工作没有进行,导致一些资源没有得到回收,导致内存泄漏;
2.stop()停止线程会导致对锁定的对象进行解锁,在多线程情况下导致数据不一致问题。
interrupt()方法
interrupt()方法为为调用该方法的线程对象设置一个中断标志,注意!这里是设置一个中断标志,丝毫不耽误线程没羞没臊的运行。请看例子
1 public class App { 2 public static void main(String[] args) { 3 4 try { 5 MyThread thread = new MyThread(); 6 thread.start(); 7 thread.interrupt(); 8 System.out.println("执行了interrupt方法"); 9 } catch (Exception e) { 10 e.printStackTrace(); 11 } 12 } 13 14 } 15 16 class MyThread extends Thread { 17 18 public void run() { 19 try{ 20 for(int i=0;i<5000;i++){ 21 System.out.println(i); 22 } 23 }catch(Exception e){ 24 e.printStackTrace(); 25 } 26 } 27 }
运行结果:
1 .... 2 4992 3 4993 4 4994 5 4995 6 4996 7 4997 8 4998 9 4999
说明在调用了interrupt之后,线程并不会停止。
使用interrupted()和isInterrupted()判断中断状态
interrupted()作用于调用该方法所在的线程,而不是调用者所在的线程,即无论哪个线程对象调用interrupted()方法,最后结果都是该方法所在线程的状态结果。
isInterrupted()作用于调用该方法的线程,即谁调用显示谁的中断状态。
并且interrupted()在第二次调用的时候,会恢复线程的状态,即第一次调用如果是中断状态,第二次调用将恢复为非中断状态。
而isInterruted()仅仅是查看线程的中断状态,并不会改变状态。请看下面例子
1 public class App { 2 public static void main(String[] args) { 3 4 try { 5 MyThread thread = new MyThread(); 6 thread.start(); 7 thread.interrupt(); 8 9 //显示的是主线程的中断状态,所以显示false 10 System.out.println("调用interrupted(): " + thread.interrupted()); 11 12 //main主线程调用interrupt(),是主线程状态为中断 13 Thread.currentThread().interrupt(); 14 15 //这里也可以使用Thread.currentThread().interrupted(),效果是一样的,具体原因看上面介绍 16 System.out.println("第一次调用interrupted(): " + thread.interrupted()); 17 //第二次调用,interrupted()方法又将状态恢复 18 System.out.println("第二次调用interrupted(): " + thread.interrupted()); 19 20 System.out.println("-------------------------------------------------"); 21 22 //而isInterrupted()返回的是调用者线程的中断状态,而且多次调用状态不会恢复 23 System.out.println("第一次调用isInterrupted(): " + thread.isInterrupted()); 24 System.out.println("第二次调用isInterrupted(): " + thread.isInterrupted()); 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28 } 29 } 30 31 class MyThread extends Thread { 32 33 public void run() { 34 try{ 35 while(true){ 36 37 } 38 }catch(Exception e){ 39 e.printStackTrace(); 40 } 41 } 42 }
运行结果为:
1 调用interrupted(): false 2 第一次调用interrupted(): true 3 第二次调用interrupted(): false 4 ------------------------------------------------- 5 第一次调用isInterrupted(): true 6 第二次调用isInterrupted(): true
注意:如果线程在睡眠状态中,线程状态被修改为interrupted,这是将抛出java.lang.InterruptedException异常,线程将会停止。
下面进入正题,如何正确的停止一个线程
有以下几个方式:
使用break停止线程:判断线程状态为中断时,使用break跳出run()方法中的循环,缺点是虽然跳出了循环体,但是循环体外的程序还会得到执行,并不能到达立即停止的效果
使用return停止线程:判断线程状态为中断时,使用return退出run()方法
抛出异常停止线程:通过抛出一个异常来停止线程,这是比较推荐的方式
这三种方式实现基本相似,我就拿异常法进行举例了(偷懒)。
1 public class App { 2 public static void main(String[] args) { 3 4 try { 5 MyThread thread = new MyThread(); 6 7 thread.start(); 8 Thread.sleep(2000); 9 thread.interrupt(); 10 11 while(true){ //主线程将一直运行 12 13 } 14 } catch(Exception e){ 15 e.printStackTrace(); 16 } 17 } 18 } 19 20 class MyThread extends Thread { 21 22 public void run() { 23 try{ 24 while(true){ 25 if(isInterrupted()){ 26 throw new InterruptedException(); 27 } 28 } 29 }catch(InterruptedException e){ 30 System.out.println("由于异常退出线程"); 31 e.printStackTrace(); 32 }finally{ 33 System.out.println("这是线程的finally"); 34 } 35 } 36 }
运行结果:
1 java.lang.InterruptedException 2 at com.sunyong.thread.stop.MyThread.run(App.java:31) 3 由于异常退出线程 4 这是线程的finally
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Flink 如何分流数据 2020-06-11
- 老板让你抗住千万级流量,如何做架构设计? 2020-06-11
- 如何干掉 if else 策略+工厂 2020-06-11
- 类的继承,方法重新中修饰符如何定义 2020-06-10
- SpringBoot通过web页面动态控制定时任务的启动、停止、创建 2020-06-09
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash