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