標籤:多線程 線程 java 停止線程
在多線程開發中停止線程是很重要的技術點。停止線程在Java語言中並不像break語句那樣乾脆,需要一些技巧性的處理。
一、 異常法
採用異常法來停止一個線程,首先我們需要瞭解一下兩個方法的用法:
1、interrupt()方法
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 1; i <= 10000; i++) {System.out.println("i="+i);}}public static void main(String[] args)throws Exception {MyThread thread=new MyThread();thread.start();thread.sleep(10);thread.interrupt();}}
上面的例子調用interrupt()方法來停止線程,但interrupt()方法的使用效果並不像for+break語句那樣,馬上就能停止迴圈。調用interrupt()方法僅僅是在當前線程打了一個停止的標記,並不是真的停止。那麼如果停止線程了?我們接著往下面看。
2、判斷線程是否是停止狀態
1)、 interrupted()
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 1; i <= 10000; i++) {System.out.println("i="+i);}}public static void main(String[] args)throws Exception {try{MyThread thread=new MyThread();thread.start();thread.sleep(100);thread.interrupt();System.out.println("線程停止了嗎1?--->"+thread.interrupted());System.out.println("線程停止了嗎2?--->"+thread.interrupted());}catch(Exception e){e.printStackTrace();}System.out.println("end");}}
從控制台列印的結果來看,線程沒有停止,這就是說,interrupted()測試當前線程是否中斷,因為這個當前線程就是main,它沒有中斷過,所以列印的結果是兩個false。如何使main線程產生中斷效果了。我們在看下,下面的例子:
public class MyThread{public static void main(String[] args){Thread.currentThread().interrupt();System.out.println("線程停止了嗎1?---->"+Thread.interrupted());System.out.println("線程停止了嗎2?---->"+Thread.interrupted());System.out.println("end");}}
從上面的結果來看,interrupted()方法的確判斷當前線程是否是停止狀態。但是為什麼第2個值是false。原來,
連續兩次調用該方法第一次會清除中斷狀態後,第二次調用所以返回flase。
2)、 isInterrupted()
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 1; i <= 10000; i++) {System.out.println("i="+i);}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();thread.sleep(10);thread.interrupt();System.out.println("線程停止了嗎1?--->"+thread.isInterrupted());System.out.println("線程停止了嗎2?--->"+thread.isInterrupted());}catch(Exception e){e.printStackTrace();}System.out.println("end");}}
從結果看出方法isInterrupted()並未清除,所以列印出了兩個true.
3、停止線程
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 1; i <= 10000; i++) {if(this.interrupted()){System.out.println("線程是停止狀態了,我要退出了.");break;}System.out.println("i="+i);}System.out.println("如果此處還是迴圈,那麼我就會繼續執行.線程並沒有停止");}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();thread.sleep(10);thread.interrupt();System.out.println("end");}catch(Exception e){e.printStackTrace();}}}
如果這麼寫的話,線程並沒有停止。現在我們在修改下代碼,也就是所謂的
異常法停止線程。
public class MyThread extends Thread{@Overridepublic void run() {try{for (int i = 1; i <= 10000; i++) {if(this.interrupted()){System.out.println("線程是停止狀態了,我要退出了.");throw new InterruptedException();}System.out.println("i="+i);}System.out.println("我被執行了嗎?");}catch(InterruptedException e){System.out.println("---這次線程停了---");e.printStackTrace();}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();thread.sleep(10);thread.interrupt();System.out.println("end");}catch(Exception e){e.printStackTrace();}}}
二、 在沉睡中停止如果線程在sleep()狀態下停止線程會有什麼效果了?
public class MyThread extends Thread{@Overridepublic void run() {try{System.out.println("run start");Thread.sleep(1000000);System.out.println("run end");}catch(InterruptedException e){System.out.println("sleep被停止,狀態:--->"+this.isInterrupted());e.printStackTrace();}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();thread.interrupt();thread.sleep(1000);}catch(Exception e){System.out.println("main catch");e.printStackTrace();}}}
從結果我們可以看出,線上程睡眠時候停止某一線程,會異常,並且清除停止狀態。我們前面異常停止線程,都是先睡眠,在停止線程,與之相反的操作,我寫代碼的時候需要注意下。
public class MyThread extends Thread{@Overridepublic void run() {try{for (int i = 1; i <= 10000; i++) {System.out.println("i="+i);}System.out.println("run start");Thread.sleep(1000000);System.out.println("run end");}catch(InterruptedException e){System.out.println("線程被停止了,在sleep,狀態:--->"+this.isInterrupted());e.printStackTrace();}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();thread.interrupt();}catch(Exception e){System.out.println("main catch");e.printStackTrace();}}}
三、 暴力停止
public class MyThread extends Thread{private int i=0;@Overridepublic void run() {try{while (true) {i++;System.out.println("i="+i);Thread.sleep(1000);}}catch(Exception e){e.printStackTrace();}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();Thread.sleep(6000);thread.stop();}catch(Exception e){e.printStackTrace();}}}
stop()方法已經被棄用,如果強制讓線程停止,可以會有一些清理工作沒得到完成,還有就是對鎖定的對象進行瞭解鎖,導致資料不同步的現象,所以開發時候禁止使用該方法去暴力停止線程。
四、 使用return停止線程
public class MyThread extends Thread{private int i=0;@Overridepublic void run() {try{while (true) {i++;if(this.interrupted()){System.out.println("線程停止了");return;}System.out.println("i="+i);}}catch(Exception e){e.printStackTrace();}}public static void main(String[] args){try{MyThread thread=new MyThread();thread.start();Thread.sleep(2000);thread.interrupt();}catch(Exception e){e.printStackTrace();}}}
PS:不過還是建議使用異常法來停止線程,因為在catch塊中還可以將異常向上拋,使線程停止事件得到傳播。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
java多線程之停止線程