Java中終止線程的方式主要有三種:
1、使用stop()方法,已被棄用。原因是:stop()是立即終止,會導致一些數據被到處理一部分就會被終止,而用戶並不知道哪些數據被處理,哪些沒有被處理,產生了不完整的“殘疾”數據,不符合完整性,所以被廢棄。So, forget it!
2、使用volatile標志位
看一個簡單的例子:
首先,實現一個Runnable接口,在其中定義volatile標志位,在run()方法中使用標志位控制程序運行
public class MyRunnable implements Runnable { //定義退出標志,true會一直執行,false會退出循環 //使用volatile目的是保證可見性,一處修改了標志,處處都要去主存讀取新的值,而不是使用緩存 public volatile boolean flag = true; public void run() { System.out.println("第" + Thread.currentThread().getName() + "個線程創建"); try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } //退出標志生效位置 while (flag) { } System.out.println("第" + Thread.currentThread().getName() + "個線程終止"); } }
然後,在main()方法中創建線程,在合適的時候,修改標志位,終止運行中的線程。
public class TreadTest { public static void main(String[] arg) throws InterruptedException { MyRunnable runnable = new MyRunnable(); //創建3個線程 for (int i = 1; i <= 3; i++) { Thread thread = new Thread(runnable, i + ""); thread.start(); } //線程休眠 Thread.sleep(2000L); System.out.println("——————————————————————————"); //修改退出標志,使線程終止 runnable.flag = false; } }
最後,運行結果,如下:
第1個線程創建 第2個線程創建 第3個線程創建 -------------------------- 第3個線程終止 第1個線程終止 第2個線程終止
3、使用interrupt()中斷的方式,注意使用interrupt()方法中斷正在運行中的線程只會修改中斷狀態位,可以通過isInterrupted()判斷。如果使用interrupt()方法中斷阻塞中的線程,那麼就會拋出InterruptedException異常,可以通過catch捕獲異常,然後進行處理後終止線程。有些情況,我們不能判斷線程的狀態,所以使用interrupt()方法時一定要慎重考慮。
第一種:正在運行中終止
public class MyThread extends Thread { public void run(){ super.run(); try { for(int i=0; i<500000; i++){ if(this.interrupted()) { System.out.println("線程已經終止, for循環不再執行"); throw new InterruptedException(); } System.out.println("i="+(i+1)); } System.out.println("這是for循環外面的語句,也會被執行"); } catch (InterruptedException e) { System.out.println("進入MyThread.java類中的catch了。。。"); e.printStackTrace(); } } }
public class Run { public static void main(String args[]){ Thread thread = new MyThread(); thread.start(); try { Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }
運行結果如下:
... i=203798 i=203799 i=203800 線程已經終止, for循環不再執行 進入MyThread.java類中的catch了。。。 java.lang.InterruptedException at thread.MyThread.run(MyThread.java:13)
第二種:阻塞狀態(sleep,wait等)終止
public class MyThread extends Thread { public void run(){ super.run(); try { System.out.println("線程開始。。。"); Thread.sleep(200000); System.out.println("線程結束。"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止, 進入catch, 調用isInterrupted()方法的結果是:" + this.isInterrupted()); e.printStackTrace(); } } }
線程開始。。。 在沉睡中被停止, 進入catch, 調用isInterrupted()方法的結果是:false java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at thread.MyThread.run(MyThread.java:12)
從打印的結果來看, 如果在sleep狀態下停止某一線程,會進入catch語句,並且清除停止狀態值,使之變為false。
前一個實驗是先sleep然後再用interrupt()停止,與之相反的操作在學習過程中也要注意:
public class MyThread extends Thread { public void run(){ super.run(); try { System.out.println("線程開始。。。"); for(int i=0; i<10000; i++){ System.out.println("i=" + i); } Thread.sleep(200000); System.out.println("線程結束。"); } catch (InterruptedException e) { System.out.println("先停止,再遇到sleep,進入catch異常"); e.printStackTrace(); } } } public class Run { public static void main(String args[]){ Thread thread = new MyThread(); thread.start(); thread.interrupt(); } }
運行結果:
i=9998 i=9999 先停止,再遇到sleep,進入catch異常 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at thread.MyThread.run(MyThread.java:15)
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!