java多線程之停止線程

來源:互聯網
上載者:User

標籤:多線程   線程   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多線程之停止線程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.