java中interrupt,interrupted和isInterrupted的区别
文章目錄
- isInterrupted
- interrupted
- interrupt
java中interrupt,interrupted和isInterrupted的區(qū)別
前面的文章我們講到了調(diào)用interrupt()來停止一個(gè)Thread,本文將會詳細(xì)講解java中三個(gè)非常相似的方法interrupt,interrupted和isInterrupted。
isInterrupted
首先看下最簡單的isInterrupted方法。isInterrupted是Thread類中的一個(gè)實(shí)例方法:
public boolean isInterrupted() {return isInterrupted(false);}通過調(diào)用isInterrupted()可以判斷實(shí)例線程是否被中斷。
它的內(nèi)部調(diào)用了isInterrupted(false)方法:
/*** 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);這個(gè)方法是個(gè)native方法,接收一個(gè)是否清除Interrupted標(biāo)志位的參數(shù)。
我們可以看到isInterrupted()傳入的參數(shù)是false,這就表示isInterrupted()只會判斷是否被中斷,而不會清除中斷狀態(tài)。
interrupted
interrupted是Thread中的一個(gè)類方法:
public static boolean interrupted() {return currentThread().isInterrupted(true);}我們可以看到,interrupted()也調(diào)用了isInterrupted(true)方法,不過它傳遞的參數(shù)是true,表示將會清除中斷標(biāo)志位。
注意,因?yàn)閕nterrupted()是一個(gè)類方法,調(diào)用isInterrupted(true)判斷的是當(dāng)前線程是否被中斷。注意這里currentThread()的使用。
interrupt
前面兩個(gè)是判斷是否中斷的方法,而interrupt()就是真正觸發(fā)中斷的方法。
我們先看下interrupt的定義:
public void interrupt() {if (this != Thread.currentThread())checkAccess();synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0(); // Just to set the interrupt flagb.interrupt(this);return;}}interrupt0();}從定義我們可以看到interrupt()是一個(gè)實(shí)例方法。
它的工作要點(diǎn)有下面4點(diǎn):
如果當(dāng)前線程實(shí)例在調(diào)用Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法,或者在該實(shí)例中調(diào)用了Thread.sleep(long)或Thread.sleep(long,int)方法,并且正在阻塞狀態(tài)中時(shí),則其中斷狀態(tài)將被清除,并將收到InterruptedException。
如果此線程在InterruptibleChannel上的I / O操作中處于被阻塞狀態(tài),則該channel將被關(guān)閉,該線程的中斷狀態(tài)將被設(shè)置為true,并且該線程將收到j(luò)ava.nio.channels.ClosedByInterruptException異常。
如果此線程在java.nio.channels.Selector中處于被被阻塞狀態(tài),則將設(shè)置該線程的中斷狀態(tài)為true,并且它將立即從select操作中返回。
如果上面的情況都不成立,則設(shè)置中斷狀態(tài)為true。
我們來舉個(gè)例子:
@Slf4j public class InterruptThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 1000; i++) {log.info("i= {}", (i+1));log.info("call inside thread.interrupted(): {}", Thread.interrupted());}}@Testpublic void testInterrupt(){InterruptThread thread=new InterruptThread();thread.start();thread.interrupt();//test isInterruptedlog.info("first call isInterrupted(): {}", thread.isInterrupted());log.info("second call isInterrupted(): {}", thread.isInterrupted());//test interrupted()log.info("first call outside thread.interrupted(): {}", Thread.interrupted());log.info("second call outside thread.interrupted() {}:", Thread.interrupted());log.info("thread is alive : {}",thread.isAlive() );} }輸出結(jié)果如下:
13:07:17.804 [main] INFO com.flydean.InterruptThread - first call isInterrupted(): true 13:07:17.808 [main] INFO com.flydean.InterruptThread - second call isInterrupted(): true13:07:17.808 [Thread-1] INFO com.flydean.InterruptThread - call inside thread.interrupted(): true 13:07:17.808 [Thread-1] INFO com.flydean.InterruptThread - call inside thread.interrupted(): false13:07:17.808 [main] INFO com.flydean.InterruptThread - first call outside thread.interrupted(): false 13:07:17.809 [main] INFO com.flydean.InterruptThread - second call outside thread.interrupted() false上面的例子中,兩次調(diào)用thread.isInterrupted()的值都是true。
在線程內(nèi)部調(diào)用Thread.interrupted(), 只有第一次返回的是ture,后面返回的都是false,這表明第一次被重置了。
在線程外部,因?yàn)椴]有中斷外部線程,所以返回的值一直都是false。
本文的例子參考https://github.com/ddean2009/learn-java-concurrency/tree/master/interrupt
更多精彩內(nèi)容且看:
- 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學(xué),超級賬本,以太坊,Libra,比特幣等持續(xù)更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續(xù)更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續(xù)更新
- java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細(xì)文章教程
更多教程請參考 flydean的博客
總結(jié)
以上是生活随笔為你收集整理的java中interrupt,interrupted和isInterrupted的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中的Atomic类
- 下一篇: java中的daemon thread