“你好,阿米戈!你不得不承認艾莉的取消計劃非常棒。”

“是的。”

“實際上, Thread類中存在類似的東西。只是變量不叫isCancel。它叫isInterrupt。用於停止線程的方法不是cancel()。它是interrupt()。”

“真的嗎?”

“是的。檢查一下:”

代碼 描述
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
因為多個線程可以在同一個 Clock 對像上調用 run 方法,所以我們得到當前線程的 Thread 對象

只要當前線程的isInterrupt變量為 false,Clock 類就會每秒向控制台寫入一次“Tick”一詞。

isInterrupt變為true時,run 方法終止。

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
主線程啟動一個應該永遠運行的子線程(時鐘)。

等待 10 秒, 調用中斷方法取消任務。

主線程完成它的工作。

時鐘線程結束它的工作。

此外,人們非常喜歡在run方法中無限循環使用的sleep方法會自動檢查isInterrupt變量。如果線程調用sleep方法,該方法首先檢查該線程的isInterrupt是否為真。如果為真,則該方法不會休眠。相反,它拋出一個InterruptedException異常。

“為什麼要拋出異常?簡單地將 isInterrupted() 而不是 isCancel() 放入循環中不是更好嗎?”

首先run方法並不總是有一個循環。該方法可能只包含對其他方法的幾十次調用。然後您必須在每個方法調用之前添加一個 isInterrupted 檢查。”

其次,一些涉及許多不同動作的方法可能需要很長時間才能執行。”

第三,拋出異常不會取代 isInterrupted 檢查。這只是一個方便的添加。拋出的異常讓您可以快速將調用堆棧展開回 run方法本身。”

第四,sleep 方法被大量使用。事實證明,這個有用的方法通過隱式檢查得到了增強,同樣有用。就好像沒有人專門添加檢查一樣,但它確實存在。這是非常有價值的你正在使用別人的代碼,你不能自己添加檢查。”

第五,額外的檢查不會降低性能。調用睡眠方法意味著線程不應該做任何事情(除了睡眠),所以額外的工作不會打擾任何人。”

“這些都是嚴肅的論點。”

“最後,還有這個:你的運行方法可以調用別人的代碼——你無權訪問的代碼(源代碼和/或更改代碼的權利)。它可能沒有 isInterrupted 檢查,它可能使用“ try ... catch (Exception e) ”來捕獲所有異常。

沒有人能保證線程會被停止。只有一個線程可以停止自己。