0

0

在Java中如何处理多线程中的异常_Java并发异常处理解析

P粉602998670

P粉602998670

发布时间:2026-01-28 11:31:02

|

892人浏览过

|

来源于php中文网

原创

未捕获异常会终止线程且不传播至主线程;Runnable任务异常无法通过Future.get()获取,需改用Callable;ExecutorService中应避免shutdownNow()截断异常;ForkJoinPool支持异常冒泡,CompletableFuture需正确选用exceptionally/whenComplete/handle。

在java中如何处理多线程中的异常_java并发异常处理解析

未捕获的异常会直接终止线程,且不会传播到主线程

Java 中 Thread 默认对未捕获异常的处理是:打印堆后静默退出。这意味着如果子线程抛出 RuntimeException(如 NullPointerExceptionArrayIndexOutOfBoundsException),主线程完全感知不到,也不会中断或失败——这极易掩盖逻辑缺陷或资源泄漏问题。

  • 不要依赖 try-catch 包裹 run() 全部逻辑来“兜底”,它只解决当前线程,不解决异常传递与统一响应问题
  • 若需主线程感知子线程异常,必须显式设计通信机制(如共享 AtomicReference 或使用 Future.get()
  • Thread.setDefaultUncaughtExceptionHandler() 可设全局兜底处理器,但仅适用于未被任何 catch 捕获的异常,且每个线程可单独设置,优先级高于默认值

ExecutorService 中的 Runnable 任务无法通过 get() 获取异常

提交 RunnableExecutorService(如 Executors.newFixedThreadPool(2))时,返回的是 Future> ,调用 future.get() 永远返回 null,即使任务内部抛了异常——因为 Runnable 没有返回值,也不声明异常,JVM 不会把异常封装进 Future

  • 改用 Callable 提交任务,其 call() 方法允许抛异常,且 Future.get() 会在异常发生时抛出 ExecutionException,原始异常可通过 e.getCause() 获取
  • 若必须用 Runnable,可在任务内手动捕获并写入共享状态(如 ConcurrentLinkedQueue),再由主线程轮询检查
  • 注意:ExecutorService.shutdownNow() 不会等待正在运行的任务完成,异常可能被截断,应配合 awaitTermination() 使用

ForkJoinPool 的异常传播行为与普通线程池不同

ForkJoinPool 执行 RecursiveActionRecursiveTask 时,子任务异常默认会“向上冒泡”到 join() 调用点,但仅限于同一线程池内的父子任务链;跨池或外部线程调用 join() 时,仍需处理 ExecutionException

  • RecursiveTaskcompute() 抛异常 → 调用 fork().join() 的地方收到 ExecutionExceptiongetCause() 即原始异常
  • 若使用 invoke()(同步执行),异常会直接抛出,无需 get() 封装
  • 避免在 compute() 中吞掉异常(如空 catch),否则会导致任务静默失败,且 isCompletedAbnormally() 返回 true 但无日志线索

CompletableFuture 的异常处理要区分 whenComplete / handle / exceptionally

这三个方法都用于响应异常,但语义和触发时机完全不同,误用会导致异常被忽略或重复处理:

幻舟AI
幻舟AI

专为短片创作者打造的AI创作平台

下载

立即学习Java免费学习笔记(深入)”;

  • exceptionally(Function):仅在前序阶段抛异常时触发,返回替代值;若前序成功,该函数不执行
  • whenComplete(BiConsumer super T, ? super Throwable>):无论成功或异常都会执行,但不能修改结果(参数是 void),适合记录日志或清理资源
  • handle(BiFunction super T, ? super Throwable, ? extends R>):总执行,可返回新结果,能同时处理成功值和异常,但要注意判空 Throwable

典型陷阱:thenApply 后接 exceptionally,但如果 thenApply 内部又抛新异常,这个新异常会被下一个 exceptionally 捕获——链式调用中每层异常都只被紧邻的异常处理器捕获。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

438

2024.03.01

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

395

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

395

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

502

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

166

2025.12.24

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

31

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.7万人学习

Java 教程
Java 教程

共578课时 | 52.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号