在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語句塊能夠拋出異常到上層.