百度Android面試題之如何停止一個執行緒
前段時間去面試了百度android職位,雖然沒有通過,但是發現了很多自己的不足,回來痛定思痛,決定將所有的面試題整理到CSDN上,查漏補缺。
問:如何停止一個執行緒?
由於平時不怎麼寫多執行緒,所以直接說了個interrupt()顯然是不對的。那麼接下來我們探討一下java中如何停止一個執行緒。
Thread.stop()
該方法已經不推薦使用,它不能保證安全的退出執行緒,這裡不討論。
interrupt()方式
我們先來學習下執行緒的interrupt()、interrupted()、isInterrupted()方法的區別
interrupt():作用是中斷本執行緒,是例項方法
這裡的中斷執行緒,並非真正的把執行緒終止,而是將“中斷標記”設定為true。
在本執行緒內,中斷自身是允許的:將“中斷標記”設定成true
其他執行緒中呼叫本執行緒的interrupt(),會通過checkAccess()檢查許可權,可能丟擲SecurityException()異常。
若本執行緒當前是阻塞狀態,呼叫interrupt()後,它的“中斷執行緒”狀態被清除,並收到InterruptException異常
若本執行緒當前是執行狀態,則會將中斷標記設定為true。
interrupted()方法:判斷當前執行緒是否處於中斷狀態,是Thread的靜態方法,如下:
public static boolean interrupted() { return currentThread().isInterrupted(true); }
isInterrupted()方法:判斷呼叫執行緒是否處於中斷狀態,是例項方法
例如:
public static void main(String[] args){
Thread thread = new Thread(()->{}); //定義一個執行緒,虛擬碼沒有具體實現
thread.isInterrupted();//判斷thread是否處於中斷狀態,而不是主執行緒是否處於中斷狀態
Thread.isInterrupted(); //判斷主執行緒是否處於中斷狀態
}
那麼,接下來,我們探究如何停止一個執行緒
使用呼叫需要被中斷的執行緒的interrupt()方法,在需要被中斷的執行緒run()方法中使用isInterrupted()判斷,並catch InterruptException異常來carry需要被中斷的執行緒是阻塞的情況。程式碼如下:
public class StopThreadDemo {
public static void main(String[] args) throws InterruptedException {
NeedStopThread thread = new NeedStopThread();
thread.start();
//主執行緒sleep,此時子執行緒在執行
Thread.sleep(300);
//在主執行緒中呼叫thread.interrupt();終端該執行緒
thread.interrupt();
Thread.sleep(300);
System.out.println("is interrupted:"+thread.isInterrupted());
}
}
class NeedStopThread extends Thread {
@Override
public void run() {
try {
//這裡可以直接寫成while(!isInterrupted)為了列印這樣寫
while (true) {
//記錄當前中斷情況
boolean isInterrupted = isInterrupted();
System.out.println("isInterrupted:"+isInterrupted);
if (!isInterrupted) {
//處理業務
//Thread.sleep(5); 1處
}else{
break;
}
}
} catch (Exception e) {
System.out.println("catch e"+e.toString());
//carry執行緒阻塞時,外部呼叫interrupt()丟擲的interruptedException
}
}
}
結果:
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:true
is interrupted:false
若放開註釋1處,結果如下:
isInterrupted:false
isInterrupted:false
isInterrupted:false
isInterrupted:false
catch ejava.lang.InterruptedException: sleep interrupted
is interrupted:false
因為當外部(主執行緒)呼叫thread.interrupt()時,thread正在執行,而執行的內容是sleep(阻塞)當前執行緒。所以會丟擲異常。這也符合我們上述所說:當需要被中斷的執行緒是阻塞狀態。外部呼叫thread.interrupt(),會丟擲InterruptedException異常