1. 程式人生 > 其它 >Java中停止執行緒的3種方式

Java中停止執行緒的3種方式

在 Java 中停止執行緒的實現方法有以下 3 種:

  1. 自定義中斷識別符號,停止執行緒。
  2. 使用執行緒中斷方法 interrupt 停止執行緒。
  3. 使用 stop 停止執行緒。

其中 stop 方法為 @Deprecated 修飾的過期方法,也就是不推薦使用的過期方法,因為 stop 方法會直接停止執行緒,這樣就沒有給執行緒足夠的時間來處理停止前的儲存工作,就會造成資料不完整的問題,因此不建議使用。而自定義中斷標識也有一些問題,所以綜合來看,interrupt 方法才是最理想的停止執行緒的方法,接下來我們一起來看它們的具體差異。

1.自定義中斷識別符號

自定義中斷識別符號就是在程式中定義一個變數來決定執行緒是否要中斷執行,具體實現程式碼如下:

class FlagThread extends Thread {
    // 自定義中斷識別符號
    public volatile boolean isInterrupt = false;
	@Override
    public void run() {
        // 如果為 true -> 中斷執行
        while (!isInterrupt) {
            // 業務邏輯處理
        }
    }
}

自定義中斷識別符號的問題在於:執行緒中斷的不夠及時。因為執行緒在執行過程中,無法呼叫 while(!isInterrupt) 來判斷執行緒是否為終止狀態,它只能在下一輪執行時判斷是否要終止當前執行緒,所以它中斷執行緒不夠及時

,比如以下程式碼:

class InterruptFlag {
    // 自定義的中斷識別符號
    private static volatile boolean isInterrupt = false;

    public static void main(String[] args) throws InterruptedException {
        // 建立可中斷的執行緒例項
        Thread thread = new Thread(() -> {
            while (!isInterrupt) { // 如果 isInterrupt=true 則停止執行緒
                System.out.println("thread 執行步驟1:執行緒即將進入休眠狀態");
                try {
                    // 休眠 1s
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread 執行步驟2:執行緒執行了任務");
            }
        });
        thread.start(); // 啟動執行緒

        // 休眠 100ms,等待 thread 執行緒執行起來
        Thread.sleep(100);
        System.out.println("主執行緒:試圖終止執行緒 thread");
        // 修改中斷識別符號,中斷執行緒
        isInterrupt = true;
    }
}

以上程式碼的執行結果如下圖所示:

我們期望的是:執行緒執行了步驟 1 之後,收到中斷執行緒的指令,然後就不要再執行步驟 2 了,但從上述執行結果可以看出,使用自定義中斷識別符號是沒辦法實現我們預期的結果的,這就是自定義中斷識別符號,響應不夠及時的問題。

2.interrupt中斷執行緒

使用 interrupt 方法可以給執行任務的執行緒,傳送一箇中斷執行緒的指令,它並不直接中斷執行緒,而是傳送一箇中斷執行緒的訊號,把是否正在中斷執行緒的主動權交給程式碼編寫者。相比於自定義中斷識別符號而然,它能更及時的接收到中斷指令,如下程式碼所示:

public static void main(String[] args) throws InterruptedException {
    // 建立可中斷的執行緒例項
    Thread thread = new Thread(() -> {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("thread 執行步驟1:執行緒即將進入休眠狀態");
            try {
                // 休眠 1s
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("thread 執行緒接收到中斷指令,執行中斷操作");
                // 中斷當前執行緒的任務執行
                break;
            }
            System.out.println("thread 執行步驟2:執行緒執行了任務");
        }
    });
    thread.start(); // 啟動執行緒

    // 休眠 100ms,等待 thread 執行緒執行起來
    Thread.sleep(100);
    System.out.println("主執行緒:試圖終止執行緒 thread");
    // 修改中斷識別符號,中斷執行緒
    thread.interrupt();
}

以上程式碼的執行結果如下圖所示:

從上述結果可以看出,執行緒在接收到中斷指令之後,立即中斷了執行緒,相比於上一種自定義中斷識別符號的方法來說,它能更及時的響應中斷執行緒指令

3.stop停止執行緒

stop 方法雖然可以停止執行緒,但它已經是不建議使用的廢棄方法了,這一點可以通過 Thread 類中的原始碼發現,stop 原始碼如下:

從上面的圖片可以看出,stop 方法是被 @Deprecated 修飾的不建議使用的過期方法,並且在註釋的第一句話就說明了 stop 方法為非安全的方法。在最新版本 Java 中,此方法已經被直接移除了,所以強烈不建議使用。

總結

本文介紹了停止執行緒的 3 種方法:

  1. 自定義中斷識別符號的停止方法,此方法的缺點是不能及時響應中斷請求;
  2. 使用 interrupt 中斷執行緒方法,此方法是傳送一箇中斷訊號給執行緒,它可以及時響應中斷,也是最推薦使用的方法;
  3. 最後是 stop 方法,雖然它也可以停止執行緒,但此方法已經是過時的不建議使用的方法,在 Java 最新版本中已經被直接移除了,所以不建議使用。

是非審之於己,譭譽聽之於人,得失安之於數。

公眾號:Java面試真題解析

面試合集:https://gitee.com/mydb/interview

關注下面二維碼,訂閱更多精彩內容。

關注公眾號(加好友):


作者: 王磊的部落格
出處: http://vipstone.cnblogs.com/