百度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異常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章