本文主要總結在java中停止線程的方法
在java中有以下三種方法可以終止正在運行的線程:
1、使用退出標志
2、使用stop方法強行終止線程,但是不推薦,因為stop和suspend、resume一樣都是過時的方法
3、使用interrup方法中斷線程
本例將使用interrupt方法來停止進程,看看效果:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 1234; i++) { System.out.println("i=" + (i + 1)); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } } }
可以看出,線程沒有停止
在java的SDK中,Thread.java類裡提供了兩種方法:
(1)this.interrupted():測試當前線程是否已經中斷
(2)this.isInterrupted():測試線程是否已經中斷
首先看一下interrupted()
實戰驗證一下:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 10000; i++) { System.out.println("i=" + (i + 1)); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("是否停止1?="+thread.interrupted()); System.out.println("是否停止2?="+thread.interrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
運行結果如下:
.......................
i=9998
i=9999
i=10000
是否停止1?=false
是否停止2?=false
end!
由於interrupted是測試當前線程,當前線程為main,一直沒有中斷,所以返回兩個false
將代碼修改一下:
public class Run { 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!"); } }
返回如下信息:
是否停止1?=true
是否停止2?=false
end!
由於interrupted方法有清除狀態的功能,所以第二次返回false
再看看isInterrupted()方法
public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("是否停止1?=" + thread.isInterrupted()); System.out.println("是否停止2?=" + thread.isInterrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
運行結果:
i=123367
i=123368
是否停止1?=true
是否停止2?=true
i=123369
i=123370
i=123371
i=123372
總結:
(1)this.interrupted():測試當前線程是否已經中斷,執行後具有將狀態標志清除為false的功能
(2)this.isInterrupted():測試線程是否已經中斷,但不清除狀態標志
可以在線程中用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("已經是停止狀態了,我要退出了!"); throw new InterruptedException(); } System.out.println("i=" + (i + 1)); } System.out.println("我在for下面"); } catch (InterruptedException e) { System.out.println("進MyThread.java類run方法中的catch了!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
如果線程在sleep狀態下停止線程,有什麼效果呢?
public class MyThread extends Thread { @Override public void run() { super.run(); try { System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止!進入catch!" + this.isInterrupted()); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(200); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
運行結果:
run begin
end!
在沉睡中被停止!進入catch!false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.wuyudong.test1.MyThread.run(MyThread.java:9)
結果說明如果在sleep狀態下停止線程,會進入catch語句,並且清除停止狀態值,使之變成false
下面進行相反的操作,修改一下:
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("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("先停止,再遇到了sleep!進入catch!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); thread.interrupt(); System.out.println("end!"); } }
運行結果如下:
i=100000
run begin
先停止,再遇到了sleep!進入catch!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.wuyudong.test1.MyThread.run(MyThread.java:12)
使用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 (InterruptedException e) { System.out.println("先停止,再遇到了sleep!進入catch!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(8000); thread.stop(); } catch (Exception e) { e.printStackTrace(); } } }
運行結果如下:
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
調用stop方法的時候會拋出java.lang.ThreadDeath異常,但是通常此異常不需要顯式地捕捉
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 (InterruptedException e) { System.out.println("先停止,再遇到了sleep!進入catch!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(8000); thread.stop(); } catch (Exception e) { e.printStackTrace(); } } }
將方法interrupt與return結合使用也能實現停止線程的效果
public class MyThread extends Thread { private int i = 0; @Override public void run() { super.run(); while(true){ if(this.isInterrupted()){ System.out.println("停止了!"); return; } System.out.println("timer="+System.currentTimeMillis()); } } } public class Run { public static void main(String[] args) throws InterruptedException{ try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (Exception e) { e.printStackTrace(); } } }
運行結果如下:
timer=1452841019023
timer=1452841019023
timer=1452841019023
timer=1452841019023
停止了!