詳解Java停止線程的四種方法
一、線程停止基礎知識
- interrupted(): 測試當前線程是否已經中斷。該方法為靜態方法,調用後會返回boolean值。不過調用之後會改變線程的狀態,如果是中斷狀態調用的,調用之後會清除線程的中斷狀態。
- isInterrupted(): 測試線程是否已經中斷。該方法由對象調用
- interrupt(): 標記線程為中斷狀態,不過不會中斷正在運行的線程。
- stop(): 暴力停止線程。已棄用。
二、停止線程方法1:異常法停止
線程調用interrupt()方法後,在線程的run方法中判斷當前對象的interrupted()狀態,如果是中斷狀態則拋出異常,達到中斷線程的效果。
如下示例:
MyThread.java
public class MyThread extends Thread { @Override public void run() { try { for (int i = 0; i < 500000; i++) { if (MyThread.interrupted()){ System.out.println("已經是停止狀態瞭,我要退出瞭!"); throw new InterruptedException(); } System.out.println("i = " + (i+1)); } System.out.println("如果我被輸出瞭,則代表線程沒有停止"); } catch (InterruptedException e) { System.out.println("在MyThread類中的run方法中被捕獲"); e.printStackTrace(); } } }
Main.java
/** * 根據中斷狀態退出for循環 * @Author: xjf * @Date: 2019/5/25 13:27 */ public class Main { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(100); myThread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end!"); } }
結果如下:
i = 19115
i = 19116
i = 19117
i = 19118
i = 19119
end!已經是停止狀態瞭,我要退出瞭!
在MyThread類中的run方法中被捕獲
java.lang.InterruptedException
at com.book.interrupt_exit.MyThread.run(MyThread.java:15)Process finished with exit code 0
三、停止線程方法2:在沉睡中停止
先將線程sleep,然後調用interrupt標記中斷狀態,interrupt會將阻塞狀態的線程中斷。會拋出中斷異常,達到停止線程的效果。如下示例:
MyThread.java
public class MyThread extends Thread { @Override public void run() { try { System.out.println("run-----------start"); Thread.sleep(5000); System.out.println("run-----------end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止!進入catch,線程的是否處於停止狀態:" + this.isInterrupted()); e.printStackTrace(); } } }
Main.java
public class Main { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(2000); System.out.println("狀態:"+MyThread.interrupted()); myThread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }
結果
run———–start
狀態:false
java.lang.InterruptedException: sleep interrupted
在沉睡中被停止!進入catch,線程的是否處於停止狀態:false
at java.lang.Thread.sleep(Native Method)
at com.book.sleep_interrupt.MyThread.run(MyThread.java:13)
線程先調用interrupt標記中斷狀態,然後線程再睡眠。會拋出中斷異常,達到停止線程的效果。如下:
MyThread1.java
public class MyThread1 extends Thread { @Override public void run() { try { for (int i = 0; i < 100000; i++) { System.out.println("i = " + (i+1)); } System.out.println("run begin"); //interrupt是做一個中斷標記,當時不會去中斷正在運行的線程,當該線程處於阻塞狀態時就會進行中斷 //因此,先進行interrupt後,再遇到sleep阻塞時,才會進行中斷 Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("先停止,再遇到瞭sleep! 進入catch!"); e.printStackTrace(); } } }
Main1.java
public class Main1 { public static void main(String[] args) { MyThread1 myThread1 = new MyThread1(); myThread1.start(); myThread1.interrupt(); System.out.println("end!"); } }
結果:
i = 99993
i = 99994
i = 99995
i = 99996
i = 99997
i = 99998
i = 99999
i = 100000
run begin先停止,再遇到瞭sleep! 進入catch!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.book.sleep_interrupt.MyThread1.run(MyThread1.java:19)
四、停止線程方法3:stop()暴力停止
線程調用stop()方法會被暴力停止,方法已棄用。該方法會有不好的後果:
- 強制讓線程停止有可能使一些請理性的工作得不到完成。
- 對鎖定的對象進行瞭“解鎖”,導致數據得不到同步的處理,出現數據不一致的問題(比如一個方法加上瞭synchronized,並在其中進行瞭一個長時間的處理,而在處理結束之前該線程進行瞭stop(),則未完成的數據將沒有進行到同步的處理)
五、停止線程方法4:使用return停止線程
調用interrupt標記為中斷狀態後,在run方法中判斷當前線程狀態,如果為中斷狀態則return,能達到停止線程的效果。
備註:建議使用“拋異常”的方法來實現線程的停止,因為在catch塊中還可以將異常向上拋,使線程停止的事件得以傳播
參考:《Java多線程編程核心技術》
到此這篇關於詳解Java停止線程的四種方法的文章就介紹到這瞭,更多相關Java停止線程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!