在原來的jdk版本中:
提供了暫停,恢復,終止線程的方法,分別是suspend(),resume(),stop();
可是它們都存在缺陷,好比暫停suspend()方法在調用後,線程不會釋放資源(好比:鎖),而是佔有着資源進入睡眠狀態。stop()方法在調用後,一般不能保證線程的資源正常的釋放,由於他根本沒有給予線程釋放資源的機會。
正由於這些方法帶來的不良影響,使得它們被廢除。java
然而聰明的程序員仍是想出來了替代上述api的方法,程序員
原始api | 替代方案 |
---|---|
暫停和恢復 | 等待-通知機制 |
終止 | 標記法和中斷法 |
經過置標記爲相反的布爾值,來終止線程web
package Interrupt;
public class InterruptThread4 {
public static void main(String args[]) throws InterruptedException {
ThreadTest t1=new ThreadTest();
t1.start();
Thread.sleep(1000);
System.out.println(System.currentTimeMillis());
t1.stopMe();
}
static class ThreadTest extends Thread{
private boolean stopMe=false;
public void stopMe() {
this.stopMe = true;
}
@Override
public void run() {
while(true){
if(stopMe){
System.out.println("interrupt!");
break;
}
try {
System.out.println("t1 sleep");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.yield();
}
System.out.println(System.currentTimeMillis());
}
}
}
t1 sleep
1501152592588
interrupt!
1501152596589api
經過打印的時間戳對比發現,發出中斷信號和線程中斷相隔的時間爲5s,這正是線程休眠的時間。因此經過標誌來中斷線程,假設線程中有sleep()和wait()方法,它達不到當即終止的做用,必須等線程恢復正常運行或者喚醒後才能終止。jvm
Thread中斷是經過內部的標記字段來進行的,線程中斷並非使線程馬上退出,而是發送給線程一個通知,至於目標線程接到通知如何處理是由線程本身決定。這是和stop()方法強行退出是不一樣的ide
在演示實例以前,先來了解下Thread類中斷的apisvg
api | 含義 |
---|---|
public void interrupt() | 中斷線程 |
public boolean isInterrupt() | 判斷線程是否中斷 |
public static boolean interrupted | 判斷線程是否中斷,而且清除當前中斷狀態 |
package Interrupt;
public class InterruptThread3 {
public static void main(String args[]) throws InterruptedException {
Thread t1=new Thread(){
@Override
public void run() {
while(true){
if(Thread.currentThread().isInterrupted()){
System.out.println("interrupt!");
break;
}
try {
System.out.println("t1 sleep");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
//設置中斷狀態
Thread.currentThread().interrupt();
}
Thread.yield();
}
System.out.println(System.currentTimeMillis());
}
};
t1.start();
Thread.sleep(1000);
System.out.println(System.currentTimeMillis());
t1.interrupt();
}
}
1501153532961
java.lang.InterruptedException: sleep interrupted
interrupt!
at java.lang.Thread.sleep(Native Method)
1501153532963
at Interrupt.InterruptThread3$1.run(InterruptThread3.java:15)this
發現interrupt()幾乎能夠達到當即中斷的效果,可是線程必須捕獲InterruptedException異常這是前提條件。不然線程會永遠的執行下去。
至於在catch代碼塊中爲何要經過Thread.currentThread().interrupt();
來重置中斷狀態,由於當jvm由於sleep(),wait()等須要捕獲異常的方法被中斷時,在拋出InterruptedException以前,它會先清除掉線程的中斷標誌位,使得isInterrupted()返回false;spa
若是線程中有wait()和sleep()等方法,用中斷法來終止線程效果更好。
由於若是線程長久的等待下去,而沒有任何其餘線程對其喚醒或者長期的睡眠下去,標誌法根本沒法中斷,而中斷法能夠當即中斷。線程
a.要使用interrupt()方法來中斷線程,必定要在方法裏捕獲InterruptedException。
b.若是由於wait(),或sleep()等須要捕獲InterruptedException的方法被中斷時,jvm會在拋出異常以前先清除中斷標記位,使得isInterrupted()返回爲false。素以咱們要在判斷以前先從新設置好標記位
很久沒寫博客了,閃~