“你好,阿米戈!你不得不承認艾莉的取消計劃非常棒。”
“是的。”
“實際上, Thread類中存在類似的東西。只是變量不叫isCancel。它叫isInterrupt。用於停止線程的方法不是cancel()。它是interrupt()。”
“真的嗎?”
“是的。檢查一下:”
代碼 | 描述 |
---|---|
|
因為多個線程可以在同一個 Clock 對像上調用 run 方法,所以我們得到當前線程的 Thread 對象。
只要當前線程的isInterrupt變量為 false,Clock 類就會每秒向控制台寫入一次“Tick”一詞。 當isInterrupt變為true時,run 方法終止。 |
|
主線程啟動一個應該永遠運行的子線程(時鐘)。
等待 10 秒, 調用中斷方法取消任務。 主線程完成它的工作。 時鐘線程結束它的工作。 |
此外,人們非常喜歡在run方法中無限循環使用的sleep方法會自動檢查isInterrupt變量。如果線程調用sleep方法,該方法首先檢查該線程的isInterrupt是否為真。如果為真,則該方法不會休眠。相反,它拋出一個InterruptedException異常。
“為什麼要拋出異常?簡單地將 isInterrupted() 而不是 isCancel() 放入循環中不是更好嗎?”
“首先,run方法並不總是有一個循環。該方法可能只包含對其他方法的幾十次調用。然後您必須在每個方法調用之前添加一個 isInterrupted 檢查。”
“其次,一些涉及許多不同動作的方法可能需要很長時間才能執行。”
“第三,拋出異常不會取代 isInterrupted 檢查。這只是一個方便的添加。拋出的異常讓您可以快速將調用堆棧展開回 run方法本身。”
”第四,sleep 方法被大量使用。事實證明,這個有用的方法通過隱式檢查得到了增強,同樣有用。就好像沒有人專門添加檢查一樣,但它確實存在。這是非常有價值的你正在使用別人的代碼,你不能自己添加檢查。”
“第五,額外的檢查不會降低性能。調用睡眠方法意味著線程不應該做任何事情(除了睡眠),所以額外的工作不會打擾任何人。”
“這些都是嚴肅的論點。”
“最後,還有這個:你的運行方法可以調用別人的代碼——你無權訪問的代碼(源代碼和/或更改代碼的權利)。它可能沒有 isInterrupted 檢查,它可能使用“ try ... catch (Exception e) ”來捕獲所有異常。
沒有人能保證線程會被停止。只有一個線程可以停止自己。
GO TO FULL VERSION