溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java高并發(fā)InterruptedException異常問題怎么解決

發(fā)布時間:2022-08-31 10:14:12 來源:億速云 閱讀:187 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“java高并發(fā)InterruptedException異常問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“java高并發(fā)InterruptedException異常問題怎么解決”吧!

前言

InterruptedException異??赡軟]你想的那么簡單!

當我們在調(diào)用Java對象的wait()方法或者線程的sleep()方法時,需要捕獲并處理InterruptedException異常。如果我們對InterruptedException異常處理不當,則會發(fā)生我們意想不到的后果!

程序案例

例如,下面的程序代碼,InterruptedTask類實現(xiàn)了Runnable接口,在run()方法中,獲取當前線程的句柄,并在while(true)循環(huán)中,通過isInterrupted()方法來檢測當前線程是否被中斷,如果當前線程被中斷就退出while(true)循環(huán),同時,在while(true)循環(huán)中,還有一行Thread.sleep(100)代碼,并捕獲了InterruptedException異常。

整個代碼如下所示。

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 線程測試中斷
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

上述代碼的本意是通過isInterrupted()方法檢查線程是否被中斷了,如果中斷了就退出while循環(huán)。其他線程通過調(diào)用執(zhí)行線程的interrupt()方法來中斷執(zhí)行線程,此時會設(shè)置執(zhí)行線程的中斷標志位,從而使currentThread.isInterrupted()返回true,這樣就能夠退出while循環(huán)。

這看上去沒啥問題啊!但真的是這樣嗎?我們創(chuàng)建一個InterruptedTest類用于測試,代碼如下所示。

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 測試線程中斷
 */
public class InterruptedTest {
    public static void main(String[] args){
        InterruptedTask interruptedTask = new InterruptedTask();
        Thread interruptedThread = new Thread(interruptedTask);
        interruptedThread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        interruptedThread.interrupt();
    }
}

我們運行main方法,如下所示。

java高并發(fā)InterruptedException異常問題怎么解決

問題分析

上述代碼明明調(diào)用了線程的interrupt()方法來中斷線程,但是卻并沒有起到啥作用。原因是線程的run()方法在執(zhí)行的時候,大部分時間都是阻塞在sleep(100)上,當其他線程通過調(diào)用執(zhí)行線程的interrupt()方法來中斷執(zhí)行線程時,大概率的會觸發(fā)InterruptedException異常,在觸發(fā)InterruptedException異常的同時,JVM會同時把線程的中斷標志位清除,所以,這個時候在run()方法中判斷的currentThread.isInterrupted()會返回false,也就不會退出當前while循環(huán)了。

既然問題分析清除了,那如何中斷線程并退出程序呢?

問題解決

正確的處理方式應(yīng)該是在InterruptedTask類中的run()方法中的while(true)循環(huán)中捕獲異常之后重新設(shè)置中斷標志位,所以,正確的InterruptedTask類的代碼如下所示。

package io.binghe.concurrent.lab08;
/**
 * @author binghe
 * @version 1.0.0
 * @description 中斷線程測試
 */
public class InterruptedTask implements Runnable{
    @Override
    public void run() {
        Thread currentThread = Thread.currentThread();
        while (true){
            if(currentThread.isInterrupted()){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
                currentThread.interrupt();
            }
        }
    }
}

可以看到,我們在捕獲InterruptedException異常的catch代碼塊中新增了一行代碼。

currentThread.interrupt();

這就使得我們捕獲到InterruptedException異常后,能夠重新設(shè)置線程的中斷標志位,從而中斷當前執(zhí)行的線程。

我們再次運行InterruptedTest類的main方法,如下所示。

java高并發(fā)InterruptedException異常問題怎么解決

總結(jié)

處理InterruptedException異常時要小心,如果在調(diào)用執(zhí)行線程的interrupt()方法中斷執(zhí)行線程時,拋出了InterruptedException異常,則在觸發(fā)InterruptedException異常的同時,JVM會同時把執(zhí)行線程的中斷標志位清除,此時調(diào)用執(zhí)行線程的isInterrupted()方法時,會返回false。

此時,正確的處理方式是在執(zhí)行線程的run()方法中捕獲到InterruptedException異常,并重新設(shè)置中斷標志位(也就是在捕獲InterruptedException異常的catch代碼塊中,重新調(diào)用當前線程的interrupt()方法)。

到此,相信大家對“java高并發(fā)InterruptedException異常問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI