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;
    }
}

以上代碼的執行結果如下圖所示:
image.png
我們期望的是:線程執行了步驟 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();
}

以上代碼的執行結果如下圖所示:
image.png
從上述結果可以看出,線程在接收到中斷指令之后,立即中斷了線程,相比於上一種自定義中斷標識符的方法來說,它能更及時的響應中斷線程指令

3.stop停止線程

stop 方法雖然可以停止線程,但它已經是不建議使用的廢棄方法了,這一點可以通過 Thread 類中的源碼發現,stop 源碼如下:
image.png
從上面的圖片可以看出,stop 方法是被 @Deprecated 修飾的不建議使用的過期方法,並且在注釋的第一句話就說明了 stop 方法為非安全的方法。在最新版本 Java 中,此方法已經被直接移除了,所以強烈不建議使用。

總結

本文介紹了停止線程的 3 種方法:

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

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

公眾號:Java面試真題解析

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM