您好,登錄后才能下訂單哦!
本篇文章為大家展示了Java中多線程的中斷機(jī)制有哪些,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
1、interrupt()
public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); // Just to set the interrupt flag b.interrupt(); return; } } interrupt0(); }
結(jié)果
/* Some private helper methods */ private native void setPriority0(int newPriority); private native void stop0(Object o); private native void suspend0(); private native void resume0(); private native void interrupt0();
分兩部分看:
(1)第一部分的第8行注釋說(shuō)得很清楚了,interrupt0()方法的作用是"Just to set the interrupt flag",即方法的作用僅僅是設(shè)置中斷標(biāo)識(shí)位
(2)第二部分的第6行就是interrupt0()方法的原型,由于方法是被native修飾的,很明顯這是一個(gè)本地方法,是Java虛擬機(jī)實(shí)現(xiàn)的
2、isInterrupted()
方法唯一的作用只是測(cè)試線程是否已經(jīng)中斷,中斷標(biāo)識(shí)位的狀態(tài)并不受到該方法的影響,看一下Java是如何實(shí)現(xiàn)這個(gè)方法的:
/** * Tests whether this thread has been interrupted. The <i>interrupted * status</i> of the thread is unaffected by this method. * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if this thread has been interrupted; * <code>false</code> otherwise. * @see #interrupted() * @revised 6.0 */ public boolean isInterrupted() { return isInterrupted(false); }
private native boolean isInterrupted(boolean ClearInterrupted);
注意一下第一部分的第2行和第3行,"The interrupted statis of the thread is unaffected by this method",即線程的中斷狀態(tài)不受到這個(gè)方法的影響。最終調(diào)用的是isInterrupted(boolean ClearInterrupted),這個(gè)方法是一個(gè)native的,看得出也是Java虛擬機(jī)實(shí)現(xiàn)的。方法的參數(shù)ClearInterrupted,顧名思義,清除中斷標(biāo)識(shí)位,這里傳遞false,明顯就是不清除
3、interrupted()
方法的作用是測(cè)試當(dāng)前線程是否已經(jīng)中斷,線程的中斷標(biāo)識(shí)位由該方法清除。換句話說(shuō),連續(xù)兩次調(diào)用該方法的返回值必定是false。看一下這個(gè)方法是如何實(shí)現(xiàn)的:
/** * Tests whether the current thread has been interrupted. The * <i>interrupted status</i> of the thread is cleared by this method. In * other words, if this method were to be called twice in succession, the * second call would return false (unless the current thread were * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if the current thread has been interrupted; * <code>false</code> otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { return currentThread().isInterrupted(true);
private native boolean isInterrupted(boolean ClearInterrupted);
同樣,第2行和第3行的注釋已經(jīng)寫得很清楚了,"Theinterruptedstatusofthethreadisclearedbythismethod",即線程的中斷狀態(tài)由此方法清除。另外,interrupted()方法和isInterrupted()方法調(diào)用的是同一個(gè)native方法,無(wú)非這個(gè)方法傳入的是true,表示清除中斷標(biāo)識(shí)位
此外,JDKAPI中有些類的方法也可能會(huì)調(diào)用中斷,比如FutureTask的cancel,如果傳入true則會(huì)在正在運(yùn)行的異步任務(wù)上調(diào)用interrupt()方法,又如ThreadPoolExecutor中的shutdownNow方法會(huì)遍歷線程池中的工作線程并調(diào)用線程的interrupt()方法。這些場(chǎng)景下只要代碼沒(méi)有對(duì)中斷作出響應(yīng),那么任務(wù)將一直執(zhí)行下去。
中斷處理時(shí)機(jī)
這其實(shí)是一個(gè)很寬泛的、沒(méi)有標(biāo)注答案的話題。顯然,作為一種協(xié)作機(jī)制,不會(huì)強(qiáng)求被中斷的線程一定要在某個(gè)點(diǎn)進(jìn)行中斷處理。實(shí)際上,被中斷線程只需要在合適的時(shí)候處理即可,如果沒(méi)有合適的時(shí)間點(diǎn),甚至可以不處理。"合適的時(shí)間點(diǎn)"就和業(yè)務(wù)邏輯密切相關(guān)了。
處理時(shí)機(jī)決定著程序的效率和響應(yīng)的靈敏度。頻繁的檢查中斷可能會(huì)導(dǎo)致程序執(zhí)行效率低下,較少的檢查則可能導(dǎo)致中斷請(qǐng)求得不到及時(shí)響應(yīng)。在實(shí)際場(chǎng)景中,如果性能指標(biāo)比較關(guān)鍵,可能需要建立一個(gè)測(cè)試模型來(lái)分析最佳的中斷檢測(cè)點(diǎn),以平衡性能和響應(yīng)靈敏性。
線程中斷舉例
寫了這么多理論,寫一個(gè)例子來(lái)演示一下中斷:
public static void main(String[] args) throws Exception { Runnable runnable = new Runnable() { public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("線程被中斷了"); return ; } else { System.out.println("線程沒(méi)有被中斷"); } } } }; Thread t = new Thread(runnable); t.start(); Thread.sleep(3000); t.interrupt(); System.out.println("線程中斷了,程序到這里了"); }
看一下運(yùn)行結(jié)果:
... 線程沒(méi)有被中斷 線程沒(méi)有被中斷 線程沒(méi)有被中斷 線程沒(méi)有被中斷 線程沒(méi)有被中斷 線程中斷了,程序到這里了 線程被中斷了
代碼分為以下幾步:
1、main函數(shù)起一個(gè)t線程
2、main函數(shù)3秒鐘之后給t線程打一個(gè)中斷標(biāo)識(shí)位,表示t線程要中斷
3、t線程無(wú)限輪詢自己的中斷標(biāo)識(shí)位,中斷了則打印、退出,否則一直運(yùn)行
從控制臺(tái)上打印的語(yǔ)句看到,3秒鐘中斷后,打印出該打印的語(yǔ)句后,就停止了。那這種場(chǎng)景就是前面說(shuō)的"頻繁地檢查",導(dǎo)致程序效率低下;那如果不頻繁地檢查呢,比如在while中的else分支中加上Thread.sleep(500),表示500ms即0.5s檢查一次,那這種場(chǎng)景就是前面說(shuō)的"中斷得不到及時(shí)的響應(yīng)"。
其實(shí)這個(gè)例子中,t線程完全可以不用去管這個(gè)中斷標(biāo)識(shí)位的,不去檢查就好了,只管做自己的事情,這說(shuō)明中斷標(biāo)識(shí)位設(shè)不設(shè)置是別人的事情,處不處理是我自己的事情,沒(méi)有強(qiáng)制要求必須處理中斷。
但是,那些會(huì)拋出InterruptedException的方法要除外。像sleep、wait、notify、join,這些方法遇到中斷必須有對(duì)應(yīng)的措施,可以直接在catch塊中處理,也可以拋給上一層。這些方法之所以會(huì)拋出InterruptedException就是由于Java虛擬機(jī)在實(shí)現(xiàn)這些方法的時(shí)候,本身就有某種機(jī)制在判斷中斷標(biāo)識(shí)位,如果中斷了,就拋出一個(gè)InterruptedException。
上述內(nèi)容就是Java中多線程的中斷機(jī)制有哪些,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。