在Java中沒有辦法立即停止1條線程,但是停止線程卻顯得尤其重要,如取消1個耗時操作。因此,Java提供了1種用于停止線程的機制——中斷。
public void interrupt()
將調用者線程的中斷狀態設為true。
public boolean isInterrupted()
判斷調用者線程的中斷狀態。
public static boolean interrupted
只能通過Thread.interrupted()調用。
它會做兩步操作:
以下3個方法都是通過線程對象去調用。
suspend()
暫停調用者線程,只釋放CPU履行權,不釋放鎖。
由于在不釋放資源的情況下進入眠眠狀態,容易產生死鎖。因此已過時!
resume()
恢復調用者線程,讓他處于就緒狀態。
stop()
調用stop后,其實不會保證資源被正確地釋放,它會使程序處于不正確的狀態下。
PS:stop和interrupt的區分?
要使用中斷,首先需要在可能會產生中斷的線程中不斷監聽中斷狀態,1旦產生中斷,就履行相應的中斷處理代碼。
當需要中斷線程時,調用該線程對象的interrupt函數便可。
Thread t1 = new Thread( new Runnable(){
public void run(){
// 若未產生中斷,就正常履行任務
while(!Thread.currentThread.isInterrupted()){
// 正常任務代碼……
}
// 中斷的處理代碼……
doSomething();
}
} ).start();
正常的任務代碼被封裝在while循環中,每次履行完1遍任務代碼就檢查1下中斷狀態;1旦產生中斷,則跳過while循環,直接履行后面的中斷處理代碼。
t1.interrupt();
上述代碼履行后會將t1對象的中斷狀態設為true,此時t1線程的正常任務代碼履行完成后,進入下1次while循環前Thread.currentThread.isInterrupted()的結果為true,此時退出循環,履行循環后面的中斷處理代碼。
stop函數停止線程過于暴力,它會立即停止線程,不給任何資源釋放的余地,下面介紹兩種安全停止線程的方法。
自定義1個同享的boolean類型變量,表示當前線程是不是需要中斷。
volatile boolean interrupted = false;
Thread t1 = new Thread( new Runnable(){
public void run(){
while(!interrupted){
// 正常任務代碼……
}
// 中斷處理代碼……
// 可以在這里進行資源的釋放等操作……
}
} );
Thread t2 = new Thread( new Runnable(){
public void run(){
interrupted = true;
}
} );
中斷標識
由線程對象提供,無需自己定義。
任務履行函數
Thread t1 = new Thread( new Runnable(){
public void run(){
while(!Thread.currentThread.isInterrupted()){
// 正常任務代碼……
}
// 中斷處理代碼……
// 可以在這里進行資源的釋放等操作……
}
} );
t1.interrupt();
上述兩種方法本質1樣,都是通過循環查看1個同享標記為來判斷線程是不是需要中斷,他們的區分在于:第1種方法的標識位是我們自己設定的,而第2種方法的標識位是Java提供的。除此以外,他們的實現方法是1樣的。
上述兩種方法之所以較為安全,是由于1條線程發出終止信號后,接收線程其實不會立即停止,而是將本次循環的任務履行完,再跳出循環停止線程。另外,程序員又可以在跳出循環后添加額外的代碼進行掃尾工作。
上文都在介紹如何獲得中斷狀態,那末當我們捕獲到中斷狀態后,究竟如何處理呢?