java中interrupt,interrupted和isInterrupted的区别
文章目錄
- isInterrupted
- interrupted
- interrupt
java中interrupt,interrupted和isInterrupted的區別
前面的文章我們講到了調用interrupt()來停止一個Thread,本文將會詳細講解java中三個非常相似的方法interrupt,interrupted和isInterrupted。
isInterrupted
首先看下最簡單的isInterrupted方法。isInterrupted是Thread類中的一個實例方法:
public boolean isInterrupted() {return isInterrupted(false);}通過調用isInterrupted()可以判斷實例線程是否被中斷。
它的內部調用了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);這個方法是個native方法,接收一個是否清除Interrupted標志位的參數。
我們可以看到isInterrupted()傳入的參數是false,這就表示isInterrupted()只會判斷是否被中斷,而不會清除中斷狀態。
interrupted
interrupted是Thread中的一個類方法:
public static boolean interrupted() {return currentThread().isInterrupted(true);}我們可以看到,interrupted()也調用了isInterrupted(true)方法,不過它傳遞的參數是true,表示將會清除中斷標志位。
注意,因為interrupted()是一個類方法,調用isInterrupted(true)判斷的是當前線程是否被中斷。注意這里currentThread()的使用。
interrupt
前面兩個是判斷是否中斷的方法,而interrupt()就是真正觸發中斷的方法。
我們先看下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()是一個實例方法。
它的工作要點有下面4點:
如果當前線程實例在調用Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法,或者在該實例中調用了Thread.sleep(long)或Thread.sleep(long,int)方法,并且正在阻塞狀態中時,則其中斷狀態將被清除,并將收到InterruptedException。
如果此線程在InterruptibleChannel上的I / O操作中處于被阻塞狀態,則該channel將被關閉,該線程的中斷狀態將被設置為true,并且該線程將收到java.nio.channels.ClosedByInterruptException異常。
如果此線程在java.nio.channels.Selector中處于被被阻塞狀態,則將設置該線程的中斷狀態為true,并且它將立即從select操作中返回。
如果上面的情況都不成立,則設置中斷狀態為true。
我們來舉個例子:
@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() );} }輸出結果如下:
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上面的例子中,兩次調用thread.isInterrupted()的值都是true。
在線程內部調用Thread.interrupted(), 只有第一次返回的是ture,后面返回的都是false,這表明第一次被重置了。
在線程外部,因為并沒有中斷外部線程,所以返回的值一直都是false。
本文的例子參考https://github.com/ddean2009/learn-java-concurrency/tree/master/interrupt
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
更多教程請參考 flydean的博客
總結
以上是生活随笔為你收集整理的java中interrupt,interrupted和isInterrupted的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中的Atomic类
- 下一篇: java中的daemon thread