在Java中有三种方法用于中止线程:java
1 . 使用退出标识,使线程正常退出, 也就是当run()方法完成后终止线程.ide
2 . 使用stop()方法强制中止线程, 可是不推荐这种方法, 由于stop和suspend , resume方法同样, 都是做废过时的方法, 使用这相似的方法可能致使不可预期的错误.测试
3 . 使用interrupt方法终止线程.this
一 . interrupt()spa
下述代码将使用interrupt()方法进行中止线程,可是interrupt()方法的使用效果并不像for循环中的break同样,立刻就中止循环. 调用interrupt()方法仅仅是在当前线程中打了一个中止的标记,并非真正的中止线程.因此在使用interrupt()方法的时候还须要加入一个判断才能够完成线程的中止.线程
代码段:对象
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { System.out.println("i = " + (i + 1)); } } }
运行类:get
public class Test { public static void main(String[] args) { try{ MyThread myThread = new MyThread(); Thread thread = new Thread(myThread); thread.start(); Thread.sleep(1000); thread.interrupt(); }catch (Exception e){ e.printStackTrace(); } } }
运行结果:同步
从运行结果能够看出,interrupt()方法并无将当前线程中止.io
二 . 判断线程是否中止
Java中Thread.java类中提供了两种方法进行判断线程是否中止的判断
1 . interrupted()
测试当前线程是否已经中断(会清除线程中断状态)
测试当前线程是不是中断状态,执行后具备将状态标识清除为false的功能.
2 . isInterrupted()
测试线程Thread对象是否已是中断状态,但不提供清除状态标识为false的功能.
三 . 中止线程(异常中止)
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { if (this.interrupted()) { System.out.println("Thread interrupted."); break; } System.out.println("i = " + (i + 1)); } System.out.println("end."); } }
public class Test { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); myThread.setName("test"); Thread.sleep(1000); myThread.interrupt(); System.out.println("线程名字 :" + myThread.getName()); System.out.println("线程是否中断 : " + myThread.interrupted()); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
使用这种方法将线程中止后for循环后面的代码还会继续运行, 若是for循环后面还存在一个或多个for循环,则该线程并不会结束.
因此,将第一段代码进行修改:
public class MyThread extends Thread { @Override public void run() { super.run(); try { for (int i = 0; i < 500000; i++) { if (this.interrupted()) { System.out.println("Thread interrupted."); throw new InterruptedException(); } System.out.println("i = " + (i + 1)); } System.out.println("end."); }catch (Exception e){ e.printStackTrace(); } } }
运行结果:
由两次运行结果能够看出for循环后面的end没有输出.
四 . 中止线程(睡眠中止)
先中止,在进入sleep
public class MyThread extends Thread { @Override public void run() { super.run(); try { for(int i = 0 ; i < 100000 ; i ++){ System.out.println(" i = " + (i + 1)); } System.out.println("Thread run begin"); Thread.sleep(200000); System.out.println("Thread run end"); }catch (Exception e){ System.out.println("end in sleep ." + this.interrupted()); e.printStackTrace(); } } }
public class Test { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); myThread.setName("test"); myThread.interrupt(); System.out.println("线程名字 :" + myThread.getName()); System.out.println("线程是否中断 : " + myThread.interrupted()); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
注:若是先进入sleep,在中止线程,会进入catch语句,而且清除状态值,使之变为false.
先中止在进入sleep,也会进入catch,可是不会清除状态值.
五 . 暴力中止
暴力中止即直接使用stop()方法
public class MyThread extends Thread { private int i = 0 ; @Override public void run() { super.run(); try { while(true){ i ++; System.out.println(" i = " + i ); Thread.sleep(1000); } }catch (Exception e){ e.printStackTrace(); } } }
public class Test { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); myThread.setName("test"); Thread.sleep(8000); myThread.stop(); System.out.println("线程名字 :" + myThread.getName()); System.out.println("线程是否中断 : " + myThread.interrupted()); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
注 : 方法stop和java.lang.ThreadDeath异常
在调用stop()方法时,会抛出java.lang.ThreadDeath异常,可是通常状况下不须要特地去捕获该异常
方法stop()已经做废了,由于若是强制让线程中止则有可能使一些清理性的工做没法完成,另一种状况就是对锁定的对象进行了解锁,致使数据得不到同步的处理,出现数据不一致的问题.
六 . 释放锁的不良影响
使用stop()方法中止线程释放锁之后会给数据形成不一致的结果,若是出现这样的状况,程序处理的数据就有可能遭到破坏,最终致使程序执行的流程出错.
public class Start { private String a = "a"; private String b = "b"; public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } synchronized public void printString(String username , String pswd){ try{ a = username; Thread.sleep(1000); b = pswd; }catch (Exception e){ e.printStackTrace(); } } }
public class MyThread extends Thread { private Start start; public MyThread(Start startObject){ super(); start = startObject; } @Override public void run(){ start.printString("b","bb"); } }
public class Test { public static void main(String[] args) { try { Start start = new Start(); MyThread myThread = new MyThread(start); myThread.start(); Thread.sleep(500); myThread.stop(); System.out.println("name = " + start.getA() + " ; password = " + start.getB()); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
因为stop()方法已经在JDK中呗标记为做废的方法,因此他在功能上具备缺陷,尽可能不要在程序中使用.
七 . 使用return中止线程
将方法interrupt()和return结合使线程中止.
public class MyThread extends Thread { @Override public void run(){ while(true){ if(this.isInterrupted()){ System.out.println("Thread ended."); return; } System.out.println("time = " + System.currentTimeMillis()); } } }
public class Test { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(2000); myThread.interrupt(); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
虽然有多种方法使线程中止,可是仍是建议经过catch语句块中止线程,由于catch语句块能够抛出异常到上层.