2013-04-08 68 views
6

這是一個關於舊Java的問題,當我們創建自己的線程時。一些方法如Thread.sleep(100)在被另一個線程中斷時會拋出InterruptedException。現在據我瞭解,中斷意味着另一條線索在說:現在讓我接管。爲什麼InterruptedException是一個檢查的異常?

發生這種情況時,Java爲什麼要我們處理InterruptedException

當線程互相中斷時,程序員甚至不需要關心。他應該能夠在線程之間劃分工作,並在完成時予以通知。那麼Java希望我們如何處理InteruptedException的原因是什麼?至少,它應該是RuntimeException

+0

我想這是讓開發人員在線程中斷時採取適當的行動。線程可能正在做一些關鍵任務,可能需要以正確的方式處理中斷。 – 2013-04-08 03:56:10

+0

逼你抓住它。 – EJP 2013-04-09 01:45:00

+2

請不要關閉它。這裏有一些很好的答案 – Victor 2013-04-09 03:06:09

回答

6

程序員甚至不應該需要關心,當線程打斷對方

這是不正確的。在許多情況下,您想知道中斷已經被請求,但您會稍微忽略一點,以完成您正在做的工作。

例如,假設一個線程打開文件並開始寫入一些數據。然後該線程阻塞,等待剩餘的數據被計算。假設第二個線程試圖中斷第一個線程。它應該做什麼?簡單地死了,也許你最終會得到一個腐敗的,不完整的文件?它應該通過刪除它開始寫入的文件來清理嗎?它是否應該忽略中斷請求,並等待數據的結束呢?它是否應該寫一些意思是「我在這裏被打斷」,以便下一次能夠繼續從那一點開始工作?

在另一種情況下,假設您有一個HTTP服務器。假設用戶正在訪問您的服務器,並從中下載一個大文件。你想停止服務器。應用程序將嘗試中斷所有工作線程。他們應該怎麼做?只需停止下載?或者他們是否應該等待用戶完成下載他們的文件,並且只有在他們死後,才能接受更多請求?兩種情況同樣有效。

正如你所看到的,有太多可能的場景,如果我們無法知道中斷已被請求,那將是非常可怕的。有時候,你只會讓線程死亡。有時候,你必須清理環境。有時,您希望它完成正在處理的請求,但不接受更多請求。

+2

不知道這是如何回答這個問題的 - 如果InterruptedException未被選中,上面所寫的所有內容都可以輕鬆實現。 – Peter 2016-07-13 05:12:03

+0

@Peter它被檢查的事實要求您的API的用戶可以拋出異常,以明確的方式處理它。如果它沒有被檢查和未被捕獲,它只會拋出異常並可能終止程序,這意味着所有上述的損壞文件和中斷連接的情況都是可能的。進行檢查是確保用戶絕對不會錯過處理異常的重要部分的一種方法。 – 2017-07-24 09:01:50

3

看來你在線程調度器和中斷之間混合。

線程調度器是一個本地系統,它將作業從多個線程劃分爲進程。如果太多線程處於活動狀態,則調度程序將異步工作。換句話說讓我現在接手可能是相當真實的。

一箇中斷意味着,退出你正在做的事情,並且不回到。實施這個最實際的方法是例外。

+0

根據Oracle的說法,http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html,*「一箇中斷的意思是,退出你現在正在做的事情,並且不要再回到它* *「*,不太正確。它說:「中斷表示線程應該停止它正在做的事情並做其他事情。**由程序員決定線程如何響應中斷**」。沒有標準的行爲,比如「不要回去」。中斷只是一種線程向另一線程發送信號的方式之一,並且這可以被實現爲意味着「退出」或不是 – 2013-04-08 22:26:27

0

當線程被強制中斷時,會拋出InteruptedException。這不是一種常見的情況(即當線程由調度程序切換出去時)。當另一個線程manually interupts it 或進程接收到 SIGINT信號 時,會出現這樣的示例。

+0

SIGKILL不會中斷線程;它直接殺死它們,它殺死了整個JVM進程。 – 2013-04-08 04:07:14

+0

對不起,我的意思是'SIGINT'。 – SimonC 2013-04-08 04:11:24

+0

SIGINT不會在線程上調用'.interrupt()'。它只會運行你添加的任何關閉鉤子。如果它確實中斷了線程,可能會造成嚴重破壞:您可能需要按照特定的順序終止線程,JVM如何知道正確的順序? – 2013-04-08 04:14:57

相關問題