Thread中的interrupt(),isInterrupted(),interrupted();
interrupt()
原始碼:public void interrupt() {
if (this != Thread.currentThread())
checkAccess(); //判斷此執行緒是否為當前執行緒,不等於,則進行檢查,此處有可能丟擲SecurityException異常。
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag只是設定中斷標誌
b.interrupt(this);
return;
}
}
interrupt0();
}
這個方法的作用:其作用是中斷此執行緒(此執行緒不一定是當前執行緒,而是指呼叫該方法的Thread例項所代表的執行緒),但實際上只是給執行緒設定一箇中斷標誌,執行緒仍會繼續執行。
interrupt()並不會終止處於“執行狀態”的執行緒!它會將執行緒的中斷標記設為true
若執行緒在阻塞狀態時,呼叫了它的interrupt()方法,那麼它的“中斷狀態”會被清除並且會收到一個InterruptedException異常,
isInterrupted():
原始碼:public boolean isInterrupted() {
return isInterrupted(false);//這句話表示:1:檢查呼叫該方法的執行緒
}
interrupted();
原始碼:public static boolean interrupted() {
return currentThread().isInterrupted(true); //這句話表示1:檢查當前執行緒是否被中斷,2:清除中斷狀態
}
private native boolean isInterrupted(boolean ClearInterrupted);
ClearInterrupted:true代表清除中斷狀態 false 表示不清楚中斷狀態
終止處於“阻塞狀態”的執行緒
我們通過“中斷”方式interrupt()終止處於“阻塞狀態”的執行緒。
為什麼使用interrupt()終止處於阻塞狀態的執行緒?:
1:首先阻塞狀態是執行緒呼叫了sleep,join,wait方法,使執行緒進入阻塞或者等待
2:若執行緒在阻塞狀態時,呼叫了它的interrupt()方法,那麼它的“中斷狀態”會被清除並且會收到一個InterruptedException異常,
3:這樣,我們如果捕獲了InterruptedException異常, 並將InterruptedException放在適當的為止就能終止執行緒
終止處於“執行狀態”的執行緒
我們通過“標記”方式isInterrupted()終止處於“執行狀態”的執行緒。其中,包括“中斷標記”和“額外新增標記”。
為什麼可以使用isInterrupted()終止處於執行狀態的執行緒,
1:isInterrupted()是判斷執行緒的中斷標記是不是為true
2:當執行緒處於執行狀態,並且我們需要終止它時;可以呼叫執行緒的interrupt()方法,使用執行緒的中斷標記為true,這個時候就做了個標記,
3:注意:interrupt()並不會終止處於“執行狀態”的執行緒!它會將執行緒的中斷標記設為true
4:我們在執行程式碼的時候
while (!isInterrupted()) {
// 執行任務...
}
//如果之前呼叫了interrupt()方法,這裡的判斷條件就為false,不會執行任務,這就做到了終止執行狀態中的執行緒
綜合執行緒處於“阻塞狀態”和“執行狀態”的終止方式,比較通用的終止執行緒的形式如下:
@Override
public void run() {
try {
// 1. isInterrupted()保證,只要中斷標記為true就終止執行緒。
while (!isInterrupted()) {
// 執行任務...
}
} catch (InterruptedException ie) {
// 2. InterruptedException異常保證,當InterruptedException異常產生時,執行緒被終止。
}
}