日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

高并发编程-Thread#interrupt用法及源码分析

發(fā)布時間:2025/3/21 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高并发编程-Thread#interrupt用法及源码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 官網(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 interrupted

void 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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。