Java多線程中停止線程遇到線程阻塞的處理方法詳解
Java多線程中停止線程遇到線程阻塞的處理方法詳解
線程可能被阻塞
子線程sleep的過程中, 給出中斷信號的demo
當子線程正在休眠的過程中, 去進行線程的中斷. 因此主線程要等子線程執(zhí)行到 Thread.sleep(1000);這一行代碼,因此在main線程中, 給出了Thread.sleep(500);
public class RightWayStopThreadWithSleep { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程任務 Runnable runnable = () -> { int num = 0; try { while (num <= 300 && !Thread.currentThread().isInterrupted()) { if (num % 100 == 0) { System.out.println(num + " 是100的整數(shù)"); } num++; } //執(zhí)行完成循環(huán)累加后, 執(zhí)行sleep, 此時主線程給出中斷信號 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }; //啟動線程 Thread thread = new Thread(runnable); thread.start(); //當子線程 正在休眠的過程中, 去進行線程的中斷. //因此要等子線程執(zhí)行到 Thread.sleep(1000);這一行代碼 //此處的 Thread.sleep(500); 是給子線程 循環(huán)0到300的時間用的 Thread.sleep(500); //子線程執(zhí)行完成0到300累加后, 在子線程sleep的過程中, 去給出中斷的信號 thread.interrupt(); } }
程序執(zhí)行的結(jié)果如下 :
可以看到 當子線程執(zhí)行完循環(huán)的任務后 ,響應主線程的中斷信號的方式為 拋出異常. 那是因為在子線程中, sleep方法被try catch所包裹了, 面對在sleep中,這種類似的阻塞操作的時候, 就會catch出這個異常, 打印如下的異常 ,響應中斷 java.lang.InterruptedException: sleep interrupted 通過斷點調(diào)試可以看到, 進入了catch的代碼塊.
而如果子線程沒有阻塞的狀態(tài), 那么子線程即使收到了中斷的信號, 也不會拋出異常.
如果線程在每次迭代時都阻塞
線程在每次迭代時都阻塞的代碼如下. 在子線程循環(huán)的過程中, 每次都Thread.sleep(10); 休眠10ms. 在子線程運行5s,后, 主線程給子線程發(fā)出中斷的通知.
public class RightWayStopThreadWithSleepEveryLoop { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程任務 Runnable runnable = () -> { int num = 0; try { while (num <= 10000 && !Thread.currentThread().isInterrupted()) { if (num % 100 == 0) { System.out.println(num + " 是100的整數(shù)"); } num++; //每一次循環(huán),休眠10ms Thread.sleep(10); } } catch (InterruptedException e) { e.printStackTrace(); } }; //啟動線程 Thread thread = new Thread(runnable); thread.start(); //此處的 Thread.sleep(5000); 是休眠主線程, 讓子線程運行5s, //子線程運行5s后, 給出子線程的休眠信號 Thread.sleep(5000); thread.interrupt(); } }
此時打印如下. 子線程打印出來sleep過程中被中斷的異常
與上一節(jié)線程可能被阻塞的區(qū)別是, 此時由于每一次的循環(huán),都會sleep, 因此真正判斷子線程是否被中斷, 不是使用Thread.currentThread().isInterrupted(), 而是在Thread.sleep(10); 休眠的過程中, 就能立刻的感知到了中斷通知, 就會拋出異常. 因此可以把代碼修改如下, 在子線程的while (num <= 10000) 時, 就不需要進行判斷線程是否中斷了.
public class RightWayStopThreadWithSleepEveryLoop { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程任務 Runnable runnable = () -> { int num = 0; try { while (num <= 10000) { if (num % 100 == 0) { System.out.println(num + " 是100的整數(shù)"); } num++; //每一次循環(huán),休眠10ms Thread.sleep(10); } } catch (InterruptedException e) { e.printStackTrace(); } }; //啟動線程 Thread thread = new Thread(runnable); thread.start(); //此處的 Thread.sleep(5000); 是休眠主線程, 讓子線程運行5s, //子線程運行5s后, 給出子線程的休眠信號 Thread.sleep(5000); thread.interrupt(); } }
打印的結(jié)果如下. 與加上判斷線程是否中斷的一致.
因此, 只要子線程在while循環(huán)的過程中, 每一次循環(huán)都會有讓線程進行阻塞一段時間的情況下, 就不需要加上線程是否被中斷的條件判斷 . 因為會在阻塞的過程中,檢測中斷的狀態(tài), 并且拋出異常
到此這篇關(guān)于Java多線程中停止線程遇到線程阻塞的處理方法詳解的文章就介紹到這了,更多相關(guān)Java線程阻塞的處理方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea打開項目后無法顯示目錄結(jié)構(gòu),只能顯示.iml文件問題
這篇文章主要介紹了idea打開項目后無法顯示目錄結(jié)構(gòu),只能顯示.iml文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08Java如何解決發(fā)送Post請求報Stream?closed問題
這篇文章主要介紹了Java如何解決發(fā)送Post請求報Stream?closed問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06Spring?MVC概念+項目創(chuàng)建+@RequestMappring案例代碼
Spring?MVC?是?Spring?提供的一個基于?MVC?設計模式的輕量級?Web?開發(fā)框架,本質(zhì)上相當于?Servlet,這篇文章主要介紹了Spring?MVC概念+項目創(chuàng)建+@RequestMappring,需要的朋友可以參考下2023-02-02自定義@RequestBody注解如何獲取JSON數(shù)據(jù)
這篇文章主要介紹了自定義@RequestBody注解如何獲取JSON數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04Springboot參數(shù)校驗之分組校驗、嵌套校驗的實現(xiàn)
日常開發(fā)中,免不了需要對請求參數(shù)進行校驗,諸如判空,長度,正則,集合等,復雜一點的請求參數(shù)可能會包含嵌套,分組校驗,本文就詳細的介紹一下,感興趣的可以了解一下2023-08-08