線程中斷
@see http://www.infoq.com/cn/articles/java-interrupt-mechanism
@see https://www.ibm.com/developerworks/cn/java/j-jtp05236.html
每個(gè)線程都有一個(gè)與之相關(guān)聯(lián)的 Boolean 屬性,用于表示線程的中斷狀態(tài)(interrupted status)金抡。中斷狀態(tài)初始時(shí)為 false;當(dāng)另一個(gè)線程通過(guò)調(diào)用 Thread.interrupt() 中斷一個(gè)線程時(shí)宇葱,會(huì)出現(xiàn)以下兩種情況之一:
1操漠、如果那個(gè)線程在執(zhí)行一個(gè)低級(jí)可中斷阻塞方法澄峰,例如 Thread.sleep()朱巨、 Thread.join() 或 Object.wait()他嫡,那么它將取消阻塞并拋出 InterruptedException
2秧耗、否則备籽, interrupt() 只是設(shè)置線程的中斷狀態(tài)。 在被中斷線程中運(yùn)行的代碼以后可以輪詢中斷狀態(tài)分井,看看它是否被請(qǐng)求停止正在做的事情车猬。
Java中斷機(jī)制是一種協(xié)作機(jī)制,也就是說(shuō)通過(guò)中斷并不能直接終止另一個(gè)線程尺锚,而需要被中斷的線程自己處理中斷珠闰。
中斷狀態(tài)可以通過(guò) Thread.isInterrupted() 來(lái)讀取,并且可以通過(guò)一個(gè)名為 Thread.interrupted() 的操作讀取和清除瘫辩。
interrupted
public static boolean interrupted() {
? ? return currentThread().isInterrupted(true);
}
測(cè)試當(dāng)前線程是否已經(jīng)中斷伏嗜,線程的中斷狀態(tài) 由該方法清除。
換句話說(shuō)杭朱,如果連續(xù)兩次調(diào)用該方法阅仔,則第二次調(diào)用將返回 false(在第一次調(diào)用已清除了其中斷狀態(tài)之后,且第二次調(diào)用檢驗(yàn)完中斷狀態(tài)前弧械,當(dāng)前線程再次中斷的情況除外)八酒。
isInterrupted
public boolean isInterrupted() {
? ? return isInterrupted(false);
}
測(cè)試線程是否已經(jīng)中斷。線程的中斷狀態(tài)不受該方法的影響刃唐。
/**
* Tests if some Thread has been interrupted.? The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
interrupt
public void interrupt() {
? ? if (this != Thread.currentThread())
? ? ? ? checkAccess();
? ? .
? ? interrupt0();? ? ? ? ? // Just to set the interrupt flag
? ? ...
中斷線程羞迷。僅僅是設(shè)置一個(gè)中斷標(biāo)志位。
處理中斷
一般說(shuō)來(lái)画饥,當(dāng)可能阻塞的方法聲明中有拋出InterruptedException則暗示該方法是可中斷的衔瓮,如BlockingQueue#put、BlockingQueue#take抖甘、Object#wait热鞍、Thread#sleep等,
如果程序捕獲到這些可中斷的阻塞方法拋出的InterruptedException或檢測(cè)到中斷后衔彻,這些中斷信息該如何處理薇宠?一般有以下兩個(gè)通用原則:
1、如果遇到的是可中斷的阻塞方法拋出InterruptedException艰额,可以繼續(xù)向方法調(diào)用棧的上層拋出該異常澄港,如果是檢測(cè)到中斷,則可清除中斷狀態(tài)并拋出InterruptedException柄沮,使當(dāng)前方法也成為一個(gè)可中斷的方法回梧。
2废岂、若有時(shí)候不太方便在方法上拋出InterruptedException,比如要實(shí)現(xiàn)的某個(gè)接口中的方法簽名上沒有throws InterruptedException(如Runnable run 方法)狱意,這時(shí)就可以捕獲可中斷方法的InterruptedException湖苞,
? 并通過(guò)Thread.currentThread.interrupt()來(lái)重新設(shè)置中斷狀態(tài)。