1. 程式人生 > >Java執行緒片——執行緒的關閉

Java執行緒片——執行緒的關閉

前文再續,書接上一回。前文講述瞭如何開啟執行緒以及開啟執行緒的三種方法。本文主要圍繞如何優雅的關閉Java執行緒。

在我們尋求Java執行緒的關閉關閉方式的時候,我們也許會按住Ctrl鍵進入到Thread類中閱讀原始碼,很快的我們就能找到一個stop()方法。似乎stop()方法就是結束執行緒的方法,但是事實恰恰與我們的猜想相反。stop()方法太過於暴力,會把執行到一半的執行緒給終止了,這樣執行緒執行緒資源的釋放就得不到保證。通常是沒有給與執行緒完成資源釋放工作的機會,因此會導致程式工作在不確定的狀態下。

三種結束執行緒的方法:

1.設定退出標誌,使執行緒正常退出,正常地退出run()方法後執行緒結束。

2.使用interrupt()方法終止執行緒。

3.使用stop方法強制終止執行緒(不推薦使用)

 

1.使用退出標誌終止執行緒

正常來說執行緒執行體run()方法執行完之後,執行緒就會進入死亡狀態,但是在開發過程中執行緒通常會進入一個無限迴圈,長時間地執行一些監聽的任務,只有在滿足一定條件的時候才能結束。我們可以通過一個變數來控制迴圈,那他便會在下一次迴圈前退出run()方法。

public class MyThread extends Thread {
    public volatile boolean exit = false; 
        public void run() { 
        while (!exit){
            //do something
        }
    } 
}

在這裡定義了一個由volatile 修飾的布林值變數exit,當把exit修改成true,迴圈就會退出,執行緒也就正常關閉。volatile關鍵字是的exit變數在多個執行緒中具有可見性。

2.使用interrupt()方法結束執行緒

要中斷一個Java執行緒,可呼叫執行緒類(Thread)物件的例項方法:interrupte();然而interrupte()方法並不會立即執行中斷操作;

如果在中斷時,執行緒正處於非阻塞狀態,則將中斷標誌修改為true,而在此基礎上,一旦進入阻塞狀態,則按照阻塞狀態的情況來進行處理;例如,一個執行緒在執行狀態中,其中斷標誌被設定為true,則此後,一旦執行緒呼叫了wait、jion、sleep方法中的一種,立馬丟擲一個InterruptedException,且中斷標誌被清除,重新設定為false。

我們可以總結,呼叫執行緒類的interrupted方法,其本質只是設定該執行緒的中斷標誌,將中斷標誌設定為true,並根據執行緒狀態決定是否丟擲異常。因此,通過interrupted方法真正實現執行緒的中斷原理是:開發人員根據中斷標誌的具體值,來決定如何退出執行緒。

public class ThreadTest {

    static class MyThread extends Thread {
        @Override
        public void run() {
            while (!isInterrupted()){ //非阻塞過程中通過判斷中斷標誌來退出
                try{
                    Thread.sleep(5*1000);//阻塞過程捕獲中斷異常來退出
                }catch(InterruptedException e){
                    e.printStackTrace();
                    System.out.println("ThreadSafe:run()"+e.getMessage());
                    break;//捕獲到異常之後,執行break跳出迴圈。
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Thread thread = new ThreadSafe();
        thread.start();
        System.out.println("在50秒之內按任意鍵中斷執行緒!");
        System.in.read();
        thread.interrupt();
        Thread.sleep(5000);
        System.out.println("執行緒已經退出!thread.is" + thread.isAlive());
    }

}

執行結果如下:

例子中,啟動執行緒,並在執行緒呼叫sleep()方法進入阻塞狀態的時候,主執行緒呼叫了MyThread的interrupt()方法,此時執行緒就會跑出InterruptdException結束run()方法,從而結束執行緒。從最後一句主執行緒列印中看出,MyThread結束了, 已經死亡。

That's all Thank you~

                                                                                      更多好文

                                                                              請掃描下面二維碼

                                                                                     歡迎關注~