Thread.interrupt()方法理解
多線程編程?
不客氣地說,至少有一半人認為,線程的”中斷”就是讓線程停止。
如果你也這么認為,那你對多線程編程還沒有入門。
在java中,線程的中斷(interrupt)只是改變了線程的中斷狀態,至于這個中斷狀態改變后帶來的結果,那是無法確定的,有時它更是讓停止中的線程繼續執行的唯一手段。不但不是讓線程停止運行,反而是繼續執行線程的手段。
對于執行一般邏輯的線程,如果調用它的interrupt()方法,那么對這個線程沒有任何
影響,比如線程a正在執行:
while(條件) x ++;
這樣的語句,如果其它線程調用a.interrupt();那么并不會影響a對象上運行的線程,但中斷標志會變為true。如果在其它線程里再次測試a的中斷狀態,則中斷標志為true,但并不會停止這個線程的運行。
在一個線程對象上調用interrupt()方法,真正有影響的是wait,join,sleep方法,當然這三個方法包括它們的重載方法。
請注意:[上面這三個方法都會拋出InterruptedException],記住這句話,下面我會重復。一個線程在調用interrupt()后,自己不會拋出InterruptedException異常,所以你看到interrupt()并沒有拋出這個異常,所以我上面說如果線程a正在執行while(條件) x ++;你調用a.interrupt()后線程會繼續正常地執行下去.
附:
Thread.sleep()源碼:
- 1
Object.wait()源碼:
public final native void wait(long timeout) throws InterruptedException;- 1
Thread.join()源碼
public final synchronized void join(long millis) throws InterruptedException {... }- 1
- 2
- 3
但是,如果一個線程被調用了interrupt()后,它的狀態是阻塞狀態的。而且這個狀態是由于正在執行wait,join,sleep的線程導致的,那么是會改變線程的運行結果.
一. 對于wait中的等待notify、notifyAll換新的線程,其實這個線程已經“暫停”執行,因為它正在某一對象的休息室中,這時如果它的中斷狀態被改變,那么它就會拋出異常。這個InterruptedException異常不是線程拋出的,而是wait方法,也就是對象的wait方法內部會不斷檢查在此對象上休息的線程的狀態,如果發現哪個線程的狀態被置為已中斷,則會拋出InterruptedException,意思就是這個線程不能再等待了,其意義就等同于喚醒它了,然后執行catch中的代碼。
這里唯一的區別是,被nortify/All喚醒的線程會繼續執行wait下面的語句,而在wait
中被中斷的線程則將控制權交給了catch語句。一些正常的邏輯要被放到catch中來運行。但有時這是唯一手段,比如一個線程a在某一對象b的wait中等待喚醒,其它線程必須獲取到對象b的監視鎖才能調用b.notify()[All],否則你就無法喚醒線程a,但在任何線程中可以無條件地調用a.interrupt();喚醒后的邏輯你要放在catch中,當然同notify/All一樣,繼續執行a線程的條件還是要等拿到b對象的監視鎖。
二. 對于sleep中的線程,如果你調用了Thread.sleep(一年);現在你后悔了,想讓它早
些醒過來,調用interrupt()方法就是唯一手段,只有改變它的中斷狀態,讓它從sleep中將控制權轉到處理異常的catch語句中,然后再由catch中的處理轉換到正常的邏輯。同樣,對于join中的線程你也可以這樣處理。
對于一般介紹多線程模式的書上,他們會這樣來介紹:當一個線程被中斷后,在進入wait,sleep,join方法時會拋出異常。是的,這一點也沒有錯,但是這有什么意義呢?如果你知道那個線程的狀態已經處于中斷狀態,為什么還要讓它進入這三個方法呢?當然有時是必須這么做的,但大多數時候沒有這么做的理由,所以我上面主要介紹了在已經調用這三個方法的線程上調用interrupt()方法讓它從這幾個方法的”暫停”狀態中恢復過來。這個恢復過來就可以包含兩個目的:
一. [可以使線程繼續執行],那就是在catch語句中執行醒來后的邏輯,或由catch語句
轉回正常的邏輯。總之它是從wait,sleep,join的暫停狀態活過來了。
二. [可以直接停止線程的運行],當然在catch中什么也不處理,或return,那么就完成了當前線程的使命,可以使在上面”暫停”的狀態中立即真正的”停止”。
總結
以上是生活随笔為你收集整理的Thread.interrupt()方法理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows批处理命令学习
- 下一篇: Android数据存储之SQLite