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í)行的結果如下 :

可以看到 當子線程執(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();
}
}
打印的結果如下. 與加上判斷線程是否中斷的一致.

因此, 只要子線程在while循環(huán)的過程中, 每一次循環(huán)都會有讓線程進行阻塞一段時間的情況下, 就不需要加上線程是否被中斷的條件判斷 . 因為會在阻塞的過程中,檢測中斷的狀態(tài), 并且拋出異常
到此這篇關于Java多線程中停止線程遇到線程阻塞的處理方法詳解的文章就介紹到這了,更多相關Java線程阻塞的處理方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
關于Java錯誤提示之找不到或無法加載主類的問題及正確處理方法
當我們在初學Java的是時候,類文件中是不設定包名(package)的,這種情況下注意classpath,基本上沒有問題,?本文主要說明classpath和系統(tǒng)環(huán)境變量PATH都沒問題的情況下出錯原因和正確處理方法,感興趣的朋友一起看看吧2022-01-01
mybatis-plus 表名添加前綴的實現(xiàn)方法
這篇文章主要介紹了mybatis-plus 表名添加前綴的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
Java?Stream比較兩個List的差異并取出不同的對象四種方法
今天開發(fā)一個需求時要對A和B兩個List集合遍歷,并比較出集合A有,而集合B沒有的值,下面這篇文章主要給大家介紹了關于Java?Stream比較兩個List的差異并取出不同對象的四種方法,需要的朋友可以參考下2024-01-01
Java 中Object的wait() notify() notifyAll()方法使用
這篇文章主要介紹了Java 中Object的wait() notify() notifyAll()方法使用的相關資料,需要的朋友可以參考下2017-05-05
Java LongAdder原理解析與實戰(zhàn)應用小結
LongAdder是Java 8中java.util.concurrent.atomic包引入的高性能計數(shù)器類,專為高并發(fā)場景下的數(shù)值累加操作優(yōu)化設計,本文給大家介紹Java LongAdder原理解析與實戰(zhàn)應用小結,感興趣的朋友一起看看吧2025-06-06

