本文将介绍jdk提供的api中停止线程的用法。
停止一个线程意味着在一个线程执行完任务之前放弃当前的操作,停止一个线程可以使用Thread.stop()方法,但是做好不要使用它,它是后继jdk版本中废弃的或者将不能使用的方法,大多数停止一个线程的操作使用Thread.interrupt()方法。
1.本实例将调用interrupt()方法来停止线程,创建MyThread.java,代码如下:
package com.lit.thread006; public class MyThread extends Thread{ @Override public void run() { for(int i = 0 ; i < 500000; i++){ System.out.println("i= "+(i)); } } }
再创建Run1.java,代码如下:
package com.lit.thread006; public class Run1 { public static void main(String[] args) { try { MyThread thread = new MyThread() ; thread.start(); Thread.sleep(1000); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果如下:
i= 499992 i= 499993 i= 499994 i= 499995 i= 499996 i= 499997 i= 499998 i= 499999
程序在执行thread.interrupt()之后,线程并未停下来,而是继续执行直到打印了50万行记录才结束方法。显然,interrupt并没有停止线程。
Thread.java类提供了判断线程状态的方法:
(1)this.interrupted(): 测试当前的线程是否已经中断;
(2)this.isInterrupted():测试线程是否已经中断;
两个方法的区别是:第一个方法判断的是当前的线程,是一个静态的方法,第二个方式是判断调用的线程:
2.创建Run2.java,代码如下:
package com.lit.thread006; public class Run2 { public static void main(String[] args) { try { MyThread thread = new MyThread() ; thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("1测试停止状态?"+thread.interrupted()); System.out.println("2测试停止状态?"+thread.interrupted()); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果如下:
i= 195000 i= 195001 i= 195002 1测试停止状态?false i= 195003 i= 195004
i= 195116 i= 195117 2测试停止状态?false i= 195118 i= 195119 i= 195120
输出结果是两个false,因为当前线程是main,它从未停止。
3.创建Run3.java,代码如下:
package com.lit.thread006; public class Run3 { public static void main(String[] args) { Thread.currentThread().interrupt(); System.out.println("1是否停止?"+Thread.interrupted()); System.out.println("2是否停止?"+Thread.interrupted()); } }
运行结果如下:
1是否停止?true 2是否停止?false
可以看到第二个值是false,那是因为再调用了interrupted()方法之后,返回线程的中断状态,并且清除该状态。
4.继续看一下isInterrupted()方法,创建Run4.java,代码如下:
package com.lit.thread006; public class Run4 { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); System.out.println("是否停止1?"+thread.isInterrupted()); System.out.println("是否停止2?"+thread.isInterrupted()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果如下:
i= 405655 i= 405656 是否停止1?true 是否停止2?true i= 405657 i= 405658
可以看到,isInterrupted()并未清除中断状态。
5.线程执行interrupt()之后停不下来只是做了一个停止标记,并不是真正的停止线程,那么如何停止一个线程呢?
创建StopThread.java类,代码如下:
package com.lit.thread006; public class StopThread extends Thread{ @Override public void run() { try { for(int i = 0 ; i < 500000 ; i++){ if(this.interrupted()){ System.out.println("线程已经是中断状态,线程退出!"); throw new InterruptedException(); } System.out.println("i = "+(i+1)); } } catch (InterruptedException e) { System.out.println("进入了StopThread的catch代码块"); e.printStackTrace(); } } public static void main(String[] args) { //测试 try { StopThread thread = new StopThread() ; thread.start(); Thread.sleep(1000); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("method end"); } }
运行结果如下:
i = 205738 i = 205739 i = 205740 i = 205741 method end 线程已经是中断状态,线程退出! 进入了StopThread的catch代码块 java.lang.InterruptedException at com.lit.thread006.StopThread.run(StopThread.java:10)
通过抛出异常让线程停止。
此外还可以通过return关键字停止异常,也可以使用stop()方法停止异常,但要注意的是stop()方法并不推荐使用,因为stop()方法释放锁将会给数据造成不一致的结果,停止方式太暴力。