线程池遇到未处理的异常会崩溃吗?

news2025/1/22 3:04:45

线程池中的 executesubmit 方法详解

在这里插入图片描述

目录

  1. 引言
  2. execute 方法
    • 使用示例代码
  3. submit 方法
    • 2.1 提交 Callable 任务
    • 2.2 提交 Runnable 任务
  4. 遇到未处理异常
    • 3.1 execute 方法遇到未处理异常
    • 3.2 submit 方法遇到未处理异常
  5. 小结

引言

在多线程编程中,线程池是提高性能和资源利用率的重要工具。Java 提供了 executesubmit 两种方法来提交任务到线程池。虽然它们看起来相似,但在实际使用中却有显著的区别。本文将详细介绍这两种方法的使用场景及其在处理异常时的行为差异。


execute 方法

execute 方法用于提交一个不需要返回值的任务给线程池执行。它接收一个 Runnable 类型的参数,并且不返回任何结果。

使用示例代码

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecuteDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 使用 execute 方法提交任务
        executor.execute(() -> {
            System.out.println("Task running in " + Thread.currentThread().getName());
            try {
                // 模拟任务执行
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("Task was interrupted");
            }
            System.out.println("Task finished");
        });

        // 关闭线程池
        executor.shutdown();
    }
}

说明execute 方法适用于那些只需要执行任务,而不需要关心任务执行结果的场景。


submit 方法

submit 方法用于提交一个需要返回值的任务(Callable 对象),或者不需要返回值但希望获取任务状态的任务(Runnable 对象)。它接收一个 CallableRunnable 类型的参数,并返回一个 Future 对象,通过该对象可以获取任务的执行结果或检查任务的状态。

2.1 提交 Callable 任务

示例代码:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SubmitCallableDemo {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 提交一个 Callable 任务给线程池执行
        Future<String> future = executorService.submit(() -> {
            Thread.sleep(2000); // 模拟任务执行时间
            return "Task's execution result";
        });

        try {
            // 获取任务的执行结果
            String result = future.get();
            System.out.println("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 关闭线程池
        executorService.shutdown();
    }
}

说明submit 方法适用于需要获取任务执行结果的场景,通过 Future 对象可以方便地获取返回值。

2.2 提交 Runnable 任务

示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SubmitRunnableDemo {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 提交一个 Runnable 任务给线程池执行,并获取一个 Future 对象
        Future<?> future = executorService.submit(() -> {
            System.out.println("Task is running in thread: " + Thread.currentThread().getName());
        });

        // 检查任务是否完成(这里只是为了示例,实际使用中可能不需要这样做)
        if (future.isDone()) {
            System.out.println("Task is done");
        } else {
            System.out.println("Task is not done yet");
        }

        // 关闭线程池
        executorService.shutdown();
    }
}

说明:即使提交的是 Runnable 任务,submit 方法也会返回一个 Future 对象,可以用来检查任务的状态。


遇到未处理异常

线程池在遇到未处理异常时的行为与添加任务的方法有关,execute 方法和 submit 方法的行为是不同的。

3.1 execute 方法遇到未处理异常

示例代码:

import java.util.concurrent.*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(100)
        );

        // 添加任务一
        executor.execute(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("线程名:" + tName);
            throw new RuntimeException("抛出异常");
        });

        // 添加任务二
        executor.execute(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("线程名:" + tName);
            throw new RuntimeException("抛出异常");
        });
    }
}

执行结果

线程名:pool-1-thread-1
线程名:pool-1-thread-2

说明

  • 当使用 execute 方法时,如果任务抛出未捕获的异常,线程会崩溃并打印异常信息,但不会影响其他线程的运行。
  • 在上述代码中,两个任务分别在不同的线程中执行,即使任务抛出异常,线程池仍然可以正常运行。

3.2 submit 方法遇到未处理异常

示例代码:

import java.util.concurrent.*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(100)
        );

        // 添加任务一
        Future<?> future = executor.submit(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("线程名:" + tName);
            throw new RuntimeException("抛出异常");
        });

        // 添加任务二
        Future<?> future2 = executor.submit(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("线程名:" + tName);
            throw new RuntimeException("抛出异常");
        });

        try {
            future.get();
        } catch (Exception e) {
            System.out.println("遇到异常:" + e.getMessage());
        }

        try {
            future2.get();
        } catch (Exception e) {
            System.out.println("遇到异常:" + e.getMessage());
        }
    }
}

执行结果

线程名:pool-1-thread-1
遇到异常:java.lang.RuntimeException: 抛出异常
线程名:pool-1-thread-1
遇到异常:java.lang.RuntimeException: 抛出异常

说明

  • 当使用 submit 方法时,任务抛出的异常会被封装在 Futureget 方法中,而不会直接影响执行任务的线程。
  • 线程池中的线程可以继续复用,不会因为任务抛出异常而崩溃。

小结

线程池在遇到未处理的异常时,不同添加任务的方法的执行行为是不同的:

  • execute 方法:遇到未处理的异常,线程会崩溃,并打印异常信息。
  • submit 方法:遇到未处理的异常,线程本身不会受到影响(线程可以复用),只是将异常信息封装到返回的对象 Future 中。

理解这两种方法的区别,可以帮助我们在实际开发中更好地选择适合的线程池任务提交方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2280121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年第十五届蓝桥杯青少组国赛(c++)真题—快速分解质因数

快速分解质因数 完整题目和在线测评可点击下方链接前往&#xff1a; 快速分解质因数_C_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/cpp/show-3781.htmlhttps://www.hixinao.com/tiku/cpp/show-3781.html 若如其他赛事真题可自行前往题库中心查找&#xff0c;题…

Linux内核编程(二十一)USB驱动开发

一、驱动类型 USB 驱动开发主要分为两种&#xff1a;主机侧的驱动程序和设备侧的驱动程序。一般我们编写的都是主机侧的USB驱动程序。 主机侧驱动程序用于控制插入到主机中的 USB 设备&#xff0c;而设备侧驱动程序则负责控制 USB 设备如何与主机通信。由于设备侧驱动程序通常与…

AI Agent:深度解析与未来展望

一、AI Agent的前世&#xff1a;从概念到萌芽 &#xff08;一&#xff09;早期探索 AI Agent的概念可以追溯到20世纪50年代&#xff0c;早期的AI研究主要集中在简单的规则系统上&#xff0c;这些系统的行为是确定性的&#xff0c;输出由输入决定。随着时间的推移&#xff0c;…

SuperMap iClient3D for WebGL选中抬升特效

在大屏展示系统中&#xff0c;对行政区划数据制作了立体效果&#xff0c;如果希望选中某一行政区划进行重点介绍&#xff0c;目前常见的方式是通过修改选中对象色彩、边线等方式进行实现&#xff1b;这里提供另外一种偏移动效的思路&#xff0c;并提供下钻功能&#xff0c;让地…

领域算法 - 字符串匹配算法

字符串匹配算法 文章目录 字符串匹配算法一&#xff1a;KMP算法1&#xff1a;算法概述2&#xff1a;部分匹配表3&#xff1a;算法实现 二&#xff1a;Moore算法1&#xff1a;算法概述2&#xff1a;代码实现3&#xff1a;完整实现 三&#xff1a;马拉车算法1&#xff1a;算法概述…

小红书用户作品列表 API 系列,返回值说明

item_search_shop_video-获得某书用户作品列表 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_sea…

LeetCode hot 力扣热题100 排序链表

归并忘了 直接抄&#xff01; class Solution { // 定义一个 Solution 类&#xff0c;包含链表排序的相关方法。// 使用快慢指针找到链表的中间节点&#xff0c;并断开链表为两部分ListNode* middleNode(ListNode* head) { ListNode* slow head; // 慢指针 slow 初始化为链表…

JavaScript正则表达式解析:模式、方法与实战案例

目录 一、什么是正则表达式 1.创建正则表达式 2.标志&#xff08;Flags&#xff09; 3.基本模式 &#xff08;1&#xff09;字符匹配 &#xff08;2&#xff09;位置匹配 &#xff08;3&#xff09;数量匹配 二、常用的正则表达式方法和属性 1.test()‌ 2.match()‌ …

Nginx在Linux中的最小化安装方式

1. 安装依赖 需要安装的东西&#xff1a; wget​&#xff0c;方便我们下载Nginx的包。如果是在Windows下载&#xff0c;然后使用SFTP上传到服务器中&#xff0c;那么可以不安装这个软件包。gcc g​&#xff0c;Nginx是使用C/C开发的服务器&#xff0c;等一下安装会用到其中的…

【大模型】ChatGPT 高效处理图片技巧使用详解

目录 一、前言 二、ChatGPT 4 图片处理介绍 2.1 ChatGPT 4 图片处理概述 2.1.1 图像识别与分类 2.1.2 图像搜索 2.1.3 图像生成 2.1.4 多模态理解 2.1.5 细粒度图像识别 2.1.6 生成式图像任务处理 2.1.7 图像与文本互动 2.2 ChatGPT 4 图片处理应用场景 三、文生图操…

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

-bash: /java: cannot execute binary file

在linux安装jdk报错 -bash: /java: cannot execute binary file 原因是jdk安装包和linux的不一致 程序员的面试宝典&#xff0c;一个免费的刷题平台

免费为企业IT规划WSUS:Windows Server 更新服务 (WSUS) 之快速入门教程(一)

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;&#xff0c;收不到通知请将我点击星标&#xff01;“ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…

面试--你的数据库中密码是如何存储的?

文章目录 三种分类使用 MD5 加密存储加盐存储Base64 编码:常见的对称加密算法常见的非对称加密算法https 传输加密 在开发中需要存储用户的密码&#xff0c;这个密码一定是加密存储的&#xff0c;如果是明文存储那么如果数据库被攻击了&#xff0c;密码就泄露了。 我们要对数据…

模型部署工具01:Docker || 用Docker打包模型 Build Once Run Anywhere

Docker 是一个开源的容器化平台&#xff0c;可以让开发者和运维人员轻松构建、发布和运行应用程序。Docker 的核心概念是通过容器技术隔离应用及其依赖项&#xff0c;使得软件在不同的环境中运行时具有一致性。无论是开发环境、测试环境&#xff0c;还是生产环境&#xff0c;Do…

Restormer: Efficient Transformer for High-Resolution Image Restoration解读

论文地址&#xff1a;Restormer: Efficient Transformer for High-Resolution Image Restoration。 摘要 由于卷积神经网络&#xff08;CNN&#xff09;在从大规模数据中学习可推广的图像先验方面表现出色&#xff0c;这些模型已被广泛应用于图像复原及相关任务。近年来&…

四、CSS效果

一、box-shadow box-shadow:在元素的框架上添加阴影效果 /* x 偏移量 | y 偏移量 | 阴影颜色 */ box-shadow: 60px -16px teal; /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */ box-shadow: 10px 5px 5px black; /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半…

火狐浏览器Firefox一些配置

没想到还会开这个…都是Ubuntu的错 一些个人习惯吧 标签页设置 常规-标签页 1.按最近使用顺序切换标签页 2.打开新标签而非新窗口&#xff08;讨厌好多窗口&#xff09; 3.打开新链接不直接切换过去&#xff08;很打断思路诶&#xff09; 4.关闭多个标签页时不向我确认 启动…

MECD+: 视频推理中事件级因果图推理--VLM长视频因果推理

论文链接&#xff1a;https://arxiv.org/pdf/2501.07227v1 1. 摘要及主要贡献点 摘要&#xff1a; 视频因果推理旨在从因果角度对视频内容进行高层次的理解。然而&#xff0c;目前的研究存在局限性&#xff0c;主要表现为以问答范式执行&#xff0c;关注包含孤立事件和基本因…

Python基于Django的社区爱心养老管理系统设计与实现【附源码】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…