在多線程之Thread狀態(tài)中遍膜,我們提到碗硬,當(dāng)一個線程由于各種原因,如調(diào)用obj的wait方法而轉(zhuǎn)入WAITING狀態(tài)時瓢颅,依然能夠響應(yīng)中斷恩尾。
首先需要明確的是,中斷不是線程的一種狀態(tài)惜索。下面開始說明關(guān)于中斷的三個方法特笋。
在多線程之Thread狀態(tài)中,我們提到調(diào)用notify或notifyAll能夠喚醒某個線程B巾兆,但是有這樣一種可能猎物,由于錯誤的編碼,或者其他什么原因角塑,其他線程都不會調(diào)用notify或notifyAll方法蔫磨,線程B永遠(yuǎn)不可能被喚醒。又或者基于某種原因圃伶,我們明確的表明堤如,不希望線程B處于WAITING狀態(tài)蒲列,并且跳過后續(xù)的代碼。
這樣一個顯而易見的需求就要求了搀罢,在某個線程A中蝗岖,例如主線程,Java應(yīng)該提供一種機(jī)制通知另一線程B榔至,使得線程B能夠跳出WAITING或者TIMED_WAITING狀態(tài)抵赢,這就是中斷。能夠達(dá)到上述目的的方法是Thread實例方法interrupt唧取。
需要特別注意的是:線程t如非處于WAITING或TIMED_WAITING狀態(tài)铅鲤,t.interrupt方法不會起任何作用。但是枫弟,當(dāng)線程t隨后進(jìn)入WAITING或TIMED_WAITING狀態(tài)邢享,會立即拋出中斷異常。
上述輸出中淡诗,t1會小于t2,這表明:當(dāng)主線程完成t.interrupt方法調(diào)用時袜漩,線程t還沒有進(jìn)入sychronized代碼塊,可以看到在這段時間內(nèi)奠货,線程t正常的運行座掘。但是當(dāng)線程t進(jìn)入sychronized代碼塊,并且調(diào)用o.wait方法后萍虽,主線程并沒有再次調(diào)用t.interrupt方法杉编,然而線程t依然立刻捕獲到了異常咆霜。
這表明主線程調(diào)用線程t的interrupt方法的時機(jī)是不受限制的,無需保證在線程t進(jìn)入WAITING或TIMED_WAITING狀態(tài)后調(diào)用光酣。
第二個方法依然是Thread實例的方法:isInterrupted
該方法返回Thread實例對象是否被設(shè)置了中斷
但是需要注意的是救军,如果線程t捕獲了中斷異常在前,調(diào)用isInterrupted方法在后唱遭,那么就會返回false。
換言之庆揩,線程實例的isInterrupted方法返回true跌穗,當(dāng)且僅當(dāng)主線程調(diào)用了線程t的interrupt方法蚌吸,同時在isInterrupted方法之前羹唠,線程t尚未捕獲中斷異常娄昆。
一旦線程t捕獲了中斷異常,線程t的中斷標(biāo)識就會復(fù)位哺眯,置為false
最后一個方法是Thread的靜態(tài)方法:interrupted
這個方法返回調(diào)用該靜態(tài)方法的線程扒俯,它有沒有被設(shè)置中斷
注意撼玄,和上面兩個實例不同。由于是在線程t中調(diào)用的靜態(tài)方法interrupted盏浙,因此它返回的是線程t是否被設(shè)置了中斷荔茬。
時間t1小于t2,這說明殖卑,主線程在調(diào)用了線程t的實例方法Interrupt方法坊萝,為線程t設(shè)置了中斷之后许起,程序再執(zhí)行到Thread.interrputed方法园细。
第一次調(diào)用返回Ture接校,這是意料之中的事。但是最后再一次調(diào)用鹿寻,返回了False诽凌。這說明,靜態(tài)方法interrupted方法會重置線程t的中斷痢法。