“嗨,阿米戈!

“一切新事物都只是我們忘記的舊事物。今天我將討論停止線程。我希望你已經忘記了 interrupt() 方法是如何工作的。”

“是的,艾莉,我完全忘記了。”

“好,那我提醒你。”

“在 Java 中,如果有人想停止正在運行的線程,他可以向線程發出信號。為此,您需要將 Thread 對象的隱藏變量isInterrupted設置為 true。”

“每個Thread都有一個interrupt()方法,用來設置這個標誌。當調用interrupt ()方法時, Thread對象內部的isInterrupted變量被設置為true。”

“並且當在線程上調用 Thread.sleep() 或 join() 方法時,該方法檢查是否為當前線程設置了 isInterrupted 標誌。如果設置了該標誌(變量 isInterrupted 等於 true),方法拋出一個InterruptedException。”

“在這裡,我提醒你一個古老的例子:”

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

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
Clock 的 run 方法獲取當前線程的 Thread 對象。

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

當 isInterrupt 變為真時,run 方法終止。

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

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

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

主線程完成它的工作。

時鐘線程完成它的工作。

“這裡我們使用sleep方法作為run方法中無限循環的一部分。在循環中,自動檢查isInterrupt變量。如果線程調用sleep方法,該方法首先檢查該線程的isInterrupt是否為真(一個調用 sleep 方法的方法)。如果它是真的,那麼該方法將不會睡眠。相反,它會拋出一個InterruptedException。”

“但在這個例子中,我們不斷地檢查循環條件中的 isInterrupted 變量。”

“我記得有一些我們不能使用這種方法的原因。你能提醒我一下嗎?”

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

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

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

第四,睡眠方法用得很多。事實證明,這個有用的方法被一個隱式檢查增強了,它同樣有用。就 好像沒有人專門添加檢查一樣,但它 確實存在。當你正在使用別人的代碼,你不能自己添加檢查。”

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

“這正是你之前所說的。”

“那你的說法呢,«沒有人能保證一個線程會被停止。只有一個線程可以自己停止。 »你能解釋一下嗎?”

“當然。”

“以前,在 Java 的早期版本中,線程有一個 stop() 方法。當你調用它時,JVM 實際上停止了線程。但是如果一個線程正在 JVM 之外做一些事情(例如,寫入文件或調用OS函數)這樣中斷時,中斷造成了很多問題,比如文件未關閉,系統資源未釋放等。”

” Java的創建者大會決定取消強制停止線程的方法。現在我們所能做的就是設置某個標誌(isInterrupted)並希望線程代碼編寫正確,以便處理這個標誌。這個標誌就像一個標語,上面寫著:‘線程,請停止。這非常重要!’。但它是否停止是它自己的事。”

“但是 InterruptedException 呢?”

“如果在這個線程上運行的代碼有一堆 try-catch 塊怎麼辦?即使某處發生 InterruptedException,也絕對不能保證某些 try-catch 不會捕獲它並忘記它。所以不能保證線程將停止。”

“另一件事是線程已經被認為是相當低級的編程。但我下次會告訴你。”

“你不是艾莉——你是山魯佐德!”

“那麼,阿米戈!這節課都講清楚了嗎?”

“是的。”

“好的。”