最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)編程中高頻異常的原因,場景與解決方案全解析

 更新時間:2026年03月09日 09:27:07   作者:Akk_it  
在Java并發(fā)編程中,異常處理是保障程序穩(wěn)定性的核心環(huán)節(jié),本文將深度解析4類高頻并發(fā)異常的產(chǎn)生原因、典型場景,并給出可落地的解決方案,幫你徹底避開這些坑

在 Java 并發(fā)編程中,異常處理是保障程序穩(wěn)定性的核心環(huán)節(jié)。新手開發(fā)者常常會被InterruptedExceptionIllegalMonitorStateException等并發(fā)相關(guān)異常困擾,這些異常不僅定位困難,還可能導(dǎo)致程序死鎖、數(shù)據(jù)錯亂甚至服務(wù)崩潰。本文將深度解析 4 類高頻并發(fā)異常的產(chǎn)生原因、典型場景,并給出可落地的解決方案,幫你徹底避開這些 “坑”。

一、java.lang.InterruptedException(中斷異常)

1. 異常本質(zhì)

InterruptedException受檢異常,表示線程在執(zhí)行阻塞操作(如sleep()、wait())時被其他線程中斷,導(dǎo)致阻塞狀態(tài)被強制打斷。

2. 觸發(fā)場景

當(dāng)線程調(diào)用Thread.sleep(long)、Object.wait()Thread.join()等阻塞方法時,其他線程調(diào)用該線程的interrupt()方法,就會觸發(fā)此異常。

3. 錯誤示例

public class InterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                // 線程休眠10秒
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                System.out.println("線程休眠被中斷:" + e.getMessage());
                // 重置中斷狀態(tài)(關(guān)鍵!)
                Thread.currentThread().interrupt();
            }
        });
        t1.start();
        
        // 1秒后中斷t1線程
        Thread.sleep(1000);
        t1.interrupt();
    }
}

4. 解決方案

  • 捕獲異常后重置中斷狀態(tài):異常會清除線程的中斷標(biāo)記,需調(diào)用Thread.currentThread().interrupt()恢復(fù),避免后續(xù)邏輯無法感知中斷。
  • 優(yōu)雅處理中斷:不要吞掉異常,根據(jù)業(yè)務(wù)場景決定是否終止線程(如任務(wù)取消時)。

二、java.lang.IllegalMonitorStateException(非法監(jiān)視器狀態(tài)異常)

1. 異常本質(zhì)

調(diào)用wait()、notify()、notifyAll()時,當(dāng)前線程未持有該對象的監(jiān)視器鎖(即未進入synchronized塊 / 方法),或鎖對象與調(diào)用方法的對象不一致。

2. 觸發(fā)場景

  • 場景 1:未在synchronized塊內(nèi)調(diào)用wait()/notify();
  • 場景 2:synchronized鎖定的對象 ≠ 調(diào)用wait()的對象;
  • 場景 3:混用LockCondition.await()/signal())和synchronizedwait()/notify())。

3. 錯誤示例 vs 正確示例

錯誤示例(未加 synchronized)

public class IllegalMonitorDemo {
    private static final Object lock = new Object();
    
    public static void main(String[] args) {
        // 直接調(diào)用wait(),未持有l(wèi)ock的鎖
        lock.wait(); // 拋出IllegalMonitorStateException
    }
}

正確示例

public class IllegalMonitorDemo {
    private static final Object lock = new Object();
    
    public static void main(String[] args) throws InterruptedException {
        synchronized (lock) { // 必須先獲取lock的監(jiān)視器鎖
            lock.wait(); // 正確:當(dāng)前線程持有l(wèi)ock的鎖
        }
    }
}

4. 解決方案

核心原則:調(diào)用wait()/notify()的代碼必須在synchronized塊 / 方法內(nèi),且鎖定的對象必須是調(diào)用這些方法的對象;

Lock+Condition 用法:若使用ReentrantLock,需通過Condition.await()/signal()替代wait()/notify(),且調(diào)用前需獲取Lock鎖:

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock(); // 獲取鎖
try {
    condition.await(); // 替代wait()
} finally {
    lock.unlock(); // 釋放鎖
}

三、java.util.ConcurrentModificationException(并發(fā)修改異常)

1. 異常本質(zhì)

單線程下迭代集合時修改集合(如 add/remove),或多線程同時修改非線程安全集合(如ArrayList),導(dǎo)致迭代器檢測到集合結(jié)構(gòu)被意外修改。

2. 觸發(fā)場景

ArrayList、HashMap等集合的方法(add()remove())未加鎖,多線程并發(fā)修改時,迭代器的modCount(修改次數(shù))與expectedModCount不一致,觸發(fā)異常。

3. 錯誤示例(多線程修改 ArrayList)

public class ConcurrentModificationDemo {
    private static final List<Integer> list = new ArrayList<>();
    
    public static void main(String[] args) {
        // 線程1:循環(huán)添加元素
        new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                list.add(i);
            }
        }).start();
        
        // 線程2:循環(huán)迭代并修改
        new Thread(() -> {
            for (Integer num : list) { // 迭代時觸發(fā)檢查
                list.remove(num); // 拋出ConcurrentModificationException
            }
        }).start();
    }
}

4. 解決方案

  • 單線程場景:迭代時修改集合需使用迭代器的remove()方法,而非集合的remove();
  • 多線程場景
    • 方案 1:使用線程安全集合(如CopyOnWriteArrayList、ConcurrentHashMap);
    • 方案 2:對非線程安全集合加鎖(如synchronizedReentrantLock);
    • 方案 3:使用Collections.synchronizedList(new ArrayList<>())包裝集合(注意:迭代時仍需手動加鎖)。

正確示例(CopyOnWriteArrayList)

// 線程安全的ArrayList替代方案
private static final List<Integer> list = new CopyOnWriteArrayList<>();

四、java.util.concurrent.RejectedExecutionException(拒絕執(zhí)行異常)

1. 異常本質(zhì)

向線程池提交任務(wù)時,線程池已達到最大處理能力(核心線程 + 非核心線程 + 任務(wù)隊列均滿),且拒絕策略為AbortPolicy(默認(rèn)),導(dǎo)致任務(wù)被拒絕執(zhí)行。

2. 觸發(fā)場景

線程池參數(shù)配置不合理,提交的任務(wù)數(shù)超過其最大容量:

  • 核心線程數(shù):corePoolSize
  • 最大線程數(shù):maximumPoolSize;
  • 任務(wù)隊列容量:workQueue.size();
  • 最大可處理任務(wù)數(shù) = maximumPoolSize + workQueue.size()

3. 錯誤示例(任務(wù)數(shù)超過線程池容量)

public class RejectedExecutionDemo {
    public static void main(String[] args) {
        // 配置線程池:核心2,最大5,隊列10,拒絕策略AbortPolicy
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 5, 60L, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10),
            new ThreadPoolExecutor.AbortPolicy() // 默認(rèn)拒絕策略:直接拋異常
        );
        
        // 提交16個任務(wù)(最大容量5+10=15),第16個被拒絕
        for (int i = 0; i < 16; i++) {
            int finalI = i;
            executor.submit(() -> {
                try {
                    Thread.sleep(1000);
                    System.out.println("執(zhí)行任務(wù):" + finalI);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        executor.shutdown();
    }
}

4. 解決方案

  • 合理配置線程池參數(shù):根據(jù)業(yè)務(wù)場景調(diào)整corePoolSize、maximumPoolSize、隊列容量,避免任務(wù)堆積;
  • 選擇合適的拒絕策略
    • AbortPolicy:默認(rèn),拋異常(適合核心任務(wù),需感知任務(wù)拒絕);
    • CallerRunsPolicy:由提交任務(wù)的線程執(zhí)行(降級處理,避免任務(wù)丟失);
    • DiscardPolicy:靜默丟棄任務(wù)(非核心任務(wù));
    • DiscardOldestPolicy:丟棄隊列最老的任務(wù),嘗試提交新任務(wù);
  • 異步降級:結(jié)合消息隊列(如 RabbitMQ)削峰填谷,避免瞬時任務(wù)量超過線程池承載能力。

優(yōu)化示例(使用 CallerRunsPolicy)

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    2, 5, 60L, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(10),
    new ThreadPoolExecutor.CallerRunsPolicy() // 提交線程執(zhí)行被拒絕的任務(wù)
);

總結(jié)

本文梳理了 Java 并發(fā)編程中 4 類高頻異常的核心要點,關(guān)鍵總結(jié)如下:

  • InterruptedException:阻塞方法被中斷時拋出,捕獲后需重置中斷狀態(tài),避免吞掉異常;
  • IllegalMonitorStateException:調(diào)用 wait/notify 前必須持有對象的監(jiān)視器鎖,Lock 需搭配 Condition 使用;
  • ConcurrentModificationException:非線程安全集合并發(fā)修改觸發(fā),優(yōu)先使用 CopyOnWriteArrayList/ConcurrentHashMap;
  • RejectedExecutionException:線程池任務(wù)超限觸發(fā),需合理配置參數(shù) + 選擇合適的拒絕策略。

以上就是Java并發(fā)編程中高頻異常的原因,場景與解決方案全解析的詳細(xì)內(nèi)容,更多關(guān)于Java并發(fā)編程高頻異常的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java 基于AQS實現(xiàn)一個同步器

    Java 基于AQS實現(xiàn)一個同步器

    這篇文章主要介紹了如何基于AQS實現(xiàn)一個同步器,幫助大家更好的理解和學(xué)習(xí)Java并發(fā),感興趣的朋友可以了解下
    2020-09-09
  • IntelliJ IDEA中使用mybatis-generator的示例

    IntelliJ IDEA中使用mybatis-generator的示例

    這篇文章主要介紹了IntelliJ IDEA中使用mybatis-generator,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • SpringBoot讀取Resource目錄文件的五種常見方式

    SpringBoot讀取Resource目錄文件的五種常見方式

    在Spring Boot開發(fā)中,我們經(jīng)常需要讀取src/main/resources目錄下的文件,src/main/resources 目錄下通常存放配置文件、模板、靜態(tài)資源、SQL腳本等,本文給大家介紹了SpringBoot讀取Resource目錄文件的五種常見方式,需要的朋友可以參考下
    2025-07-07
  • Java使用HashMap映射實現(xiàn)消費抽獎功能

    Java使用HashMap映射實現(xiàn)消費抽獎功能

    這篇文章主要為大家詳細(xì)介紹了Java使用HashMap映射實現(xiàn)消費抽獎功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringCloud與Consul集成實現(xiàn)負(fù)載均衡功能

    SpringCloud與Consul集成實現(xiàn)負(fù)載均衡功能

    負(fù)載均衡基本概念有:實服務(wù)、實服務(wù)組、虛服務(wù)、調(diào)度算法、持續(xù)性等,其常用應(yīng)用場景主要是服務(wù)器負(fù)載均衡,鏈路負(fù)載均衡。這篇文章主要介紹了SpringCloud與Consul集成實現(xiàn)負(fù)載均衡 ,需要的朋友可以參考下
    2018-09-09
  • spring boot tomcat jdbc pool的屬性綁定

    spring boot tomcat jdbc pool的屬性綁定

    這篇文章主要介紹了spring boot tomcat jdbc pool的屬性綁定的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2018-01-01
  • java前后端傳值,參數(shù)有集合類型的數(shù)據(jù)時的兩種操作方式

    java前后端傳值,參數(shù)有集合類型的數(shù)據(jù)時的兩種操作方式

    這篇文章主要介紹了java前后端傳值,參數(shù)有集合類型的數(shù)據(jù)時的兩種操作方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • JAVA中調(diào)用C語言函數(shù)的實現(xiàn)方式

    JAVA中調(diào)用C語言函數(shù)的實現(xiàn)方式

    這篇文章主要介紹了JAVA中調(diào)用C語言函數(shù)的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Mac?Maven環(huán)境搭建安裝和配置超詳細(xì)步驟

    Mac?Maven環(huán)境搭建安裝和配置超詳細(xì)步驟

    這篇文章主要給大家介紹了關(guān)于Mac?Maven環(huán)境搭建安裝和配置的超詳細(xì)步驟,Maven是一種常用的Java構(gòu)建工具,它可以自動化構(gòu)建、測試和打包Java項目,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • 深入淺析jcmd:JDK14中的調(diào)試神器

    深入淺析jcmd:JDK14中的調(diào)試神器

    這篇文章主要介紹了jcmd:JDK14中的調(diào)試神器,本文給大家提到了jcmd的語法,通過實例列舉的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04

最新評論

松江区| 林州市| 三门峡市| 泽普县| 南昌县| 尤溪县| 乐陵市| 固阳县| 浪卡子县| 内黄县| 台北县| 大方县| 鹿泉市| 永康市| 吉水县| 海林市| 罗田县| 天峻县| 新竹市| 黔江区| 克什克腾旗| 唐河县| 吕梁市| 沾益县| 鹰潭市| 奉新县| 来凤县| 沁水县| 苏尼特右旗| 张家口市| 若尔盖县| 湄潭县| 威海市| 新蔡县| 双峰县| 余江县| 黄龙县| 漯河市| 万全县| 怀远县| 喜德县|