高并发编程-Thread#interrupt用法及源码分析
文章目錄
- 官網(wǎng)
- 方法&源碼
- void interrupt()
- ` boolean isInterrupted()` vs `static boolean interrupted()`
- 方法&示例
- void interrupt()
- sleep()方法中測試interrupt
- wait()方法中測試interrupt
- join方法中測試interrupt
- boolean isInterrupted() 和 static boolean interrupted()
官網(wǎng)
我們看下Java8中Thread類關(guān)于interrupt的幾個方法
先來看下基本用法,我們后面的例子再該示例上拓展
package com.artisan.test;public class ThreadInterruptedDemo {public static void main(String[] args) {// 定義一個線程 死循環(huán) 調(diào)用start后一直運行Thread t = new Thread(() -> {while (true) {}}, "t");// 啟動線程t.start();// 查看t的狀態(tài)System.out.println("before interrupt status>>>" + t.isInterrupted());// interruptt.interrupt();// 查看t的狀態(tài)System.out.println("after interrupt status>>>" + t.isInterrupted());} }運行
方法&源碼
查看官方的API,可以看到 關(guān)于interrupt的 我們可以調(diào)用的API 主要有3個
void interrupt()----Interrupts this thread. static boolean interrupted()---Tests whether the current thread has been interrupted. boolean isInterrupted()----Tests whether this thread has been interruptedvoid interrupt()
大致意思是說:
除非當前線程正在中斷自身(始終允許),否則將調(diào)用此線程的checkAccess方法,這可能導致拋出SecurityException。
如果在調(diào)用Object類的wait(),wait(long)或wait(long,int)方法,或者join(),join(long),join(long,int)方法中阻塞了這個線程,sleep(long)或sleep(long,int),這個類的方法,然后它的中斷狀態(tài)將被清除,它將收到InterruptedException。
如果在InterruptibleChannel上的I / O操作中阻塞了該線程,則該通道將被關(guān)閉,線程的中斷狀態(tài)將被設(shè)置,并且線程將收到ClosedByInterruptException。
如果此線程在Selector中被阻塞,則線程的中斷狀態(tài)將被設(shè)置,并且它將立即從選擇操作返回,可能具有非零值,就像調(diào)用選擇器的喚醒方法一樣。
如果以前的條件都不成立,則將設(shè)置該線程的中斷狀態(tài)。
中斷不活動的線程不會產(chǎn)生任何影響
我們來看下源碼,我這里標注了下注釋
public void interrupt() {// 如果不是當前線程,拋出SecurityException異常if (this != Thread.currentThread())checkAccess();// 對blockerLock對象加鎖 private final Object blockerLock = new Object(); synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0(); // 調(diào)用interrupt0 這個native的方法 :Just to set the interrupt flagb.interrupt(this);return;}}interrupt0();}boolean isInterrupted() vs static boolean interrupted()
寫個例子 ,都在注釋里了。
方法&示例
void interrupt()
sleep()方法中測試interrupt
package com.artisan.test;public class ThreadInterruptedDemo {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (true) {try {Thread.sleep(100);} catch (InterruptedException e) { // 捕獲InterruptedExceptionSystem.out.println(Thread.currentThread().getName() + " 接收到打斷信號 ");e.printStackTrace();}}}, "t");t.start();System.out.println("before interrupt status>>>" + t.isInterrupted());// interruptt.interrupt();System.out.println("after interrupt status>>>" + t.isInterrupted());} }
雖然捕獲了InterruptedException,但是該程序依舊還是運行,并沒有退出
wait()方法中測試interrupt
package com.artisan.test;public class ThreadInterruptedDemo {private static final Object MONITOR = new Object();public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (true) {// 使用wait的時候,必須要使用synchronized 加鎖synchronized (MONITOR){try {MONITOR.wait(100);} catch (InterruptedException e) {System.out.println(Thread.currentThread().getName() + " 接收到打斷信號 ");e.printStackTrace();}}}}, "t");t.start();System.out.println("before interrupt status>>>" + t.isInterrupted());// interruptt.interrupt();System.out.println("after interrupt status>>>" + t.isInterrupted());} }使用wait的時候,必須要使用synchronized 加鎖,這里對一個Object對象加鎖
雖然捕獲了InterruptedException,但是該程序依舊還是運行,并沒有退出
join方法中測試interrupt
這個比較有意思,我們來逐步的測試下
先搭個基本的架子
package com.artisan.test;public class ThreadInterruptedDemo {public static void main(String[] args) {Thread t = new Thread(() -> {while (true) {}}, "t");// 啟動t.start();// jointry {t.join();} catch (InterruptedException e) {System.out.println("收到中斷信號...");e.printStackTrace();}System.out.println("這里永遠都不會執(zhí)行到,因為t是個死循環(huán)... ");} }因為一旦 join方法執(zhí)行了以后,后面的代碼都會被阻塞住,因此必須要在join之前開辟另外一個線程
為了直觀,我們直接貼圖吧
運行結(jié)果:
**并沒有出現(xiàn)我們期望的InterruptedException **,w t f…
我們來分析下,上面的兩個例子 。
sleep 我們sleep的是 t 線程,我們調(diào)用了t.interrupt,收到了InterruptedException
wait 我們wait的也是t 線程,我們調(diào)用了t.interrupt,收到了InterruptedException
但是我們join的時候,t.join ,這個時候join的不是線程t,是join的main線程 ,所以必須用main線程來調(diào)用interrupt , 改造下
運行日志
boolean isInterrupted() 和 static boolean interrupted()
總結(jié)
以上是生活随笔為你收集整理的高并发编程-Thread#interrupt用法及源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高并发编程-Daemon Thread的
- 下一篇: 高并发编程-Thread_正确关闭线程的