停止執行緒的多種方法
阿新 • • 發佈:2019-01-02
例一:stop強制停止執行緒
public class Thread06 extends Thread {
private int i = 0;
@Override
public void run() {
super.run();
try{
while(true) {
i ++;
System.out.println("i=" + (i + 1));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
thread06();
}
private static void thread06() {
try{
Thread06 thread = new Thread06();
thread.start();
Thread.sleep(9000);
thread.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
輸出結果
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
thread.start();方法啟動一個新的執行緒,該執行緒與main執行緒並行執行,main執行緒睡眠9秒後執行了thread.stop();方法,thread執行緒被main執行緒強制停止。
stop方法已被廢棄,因為如果強制讓執行緒停止則可能使一些清理的工作得不到完成。另外一個情況就是對鎖定的物件進行了“解鎖”,導致資料得不到同步的處理,出現數據不一致的結果。
例二:執行緒睡眠(sleep)時停止(interrupt)執行緒
public class Thread05 extends Thread {
@Override
public void run() {
super.run();
try{
for(int i = 0; i < 1000; ++ 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 static void main(String[] args) {
thread05();
}
private static void thread05() {
Thread05 thread = new Thread05();
thread.start();
thread.interrupt();
log("end!====================");
}
輸出結果:
end!====================
i=1
i=2
i=3
......
i=999
i=1000
run begin!
先停止,再遇到了sleep!進入catch
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.qbian.thread.Thread05.run(Thread05.java:12)
執行緒在睡眠時(sleep)呼叫它的停止方法(interrupt)會停止執行緒並丟擲InterruptedException異常。
例三、呼叫interrupt方法停止正在執行的執行緒,break跳出迴圈繼續執行後續程式碼
public class Thread02 extends Thread{
@Override
public void run() {
super.run();
for(int i = 0; i < 500000; ++ i) {
if(this.interrupted()) {
System.out.println("已經是停止狀態了!我要退出了!");
break;
}
System.out.println("i=" + ( i + 1));
}
System.out.println("我被輸出,執行緒並沒有完全停止!");
}
}
public static void main(String[] args) {
thread02();
}
private static void thread02() {
try{
Thread02 thread = new Thread02();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch(InterruptedException e) {
log("main catch");
e.printStackTrace();
}
log("end!");
}
輸出結果:
......
i=245329
i=245330
i=245331
i=245332
i=245333
i=245334
end!
已經是停止狀態了!我要退出了!
我被輸出,執行緒並沒有完全停止!
break只是跳出了for迴圈,並不會真正的停止執行緒,run方法內的後續程式碼會繼續執行。
例四、呼叫interrupt方法停止正在執行的執行緒,並丟擲異常阻止執行緒後續的程式碼執行
public class Thread03 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("因為丟擲了異常,所以我不會被輸出!");
} catch(InterruptedException e) {
System.out.println("進thread03類的run方法中的catch了!");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
thread03();
}
private static void thread03() {
try{
Thread03 thread = new Thread03();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch(InterruptedException e) {
log("main catch");
e.printStackTrace();
}
log("end!");
}
輸出結果:
......
i=278267
i=278268
i=278269
i=278270
i=278271
已經是停止狀態了!我要退出了!
end!
進thread03類的run方法中的catch了!
java.lang.InterruptedException
at com.qbian.thread.Thread03.run(Thread03.java:11)
主執行緒呼叫interrupt方法停止一個正在執行的執行緒,在被停止的執行緒內部判斷自身狀態是否已經停止this.interrupted(),停止的話就丟擲異常,可以阻止後續程式碼的執行,直接進入catch塊內。
例五、使用interrupt和return停止執行緒並阻止後續程式碼執行
public class Thread07 extends Thread{
@Override
public void run() {
super.run();
while(true) {
if(this.isInterrupted()) {
System.out.println("停止了!後面的時間將不會被輸出!");
return;
}
System.out.println("timer=" + System.currentTimeMillis());
}
}
}
public static void main(String[] args) {
thread07();
}
private static void thread07() {
try {
Thread07 thread = new Thread07();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
log("main catch");
e.printStackTrace();
}
}
輸出結果:
......
timer=1496420116082
timer=1496420116082
timer=1496420116082
停止了!後面的時間將不會被輸出!
推薦使用丟擲異常的方式停止執行緒執行,因為在catch塊中還可以將異常向上拋,使執行緒停止的事件得到傳播。