当前位置:首页 > 科技  > 软件

Java线程池中线程异常后:是销毁还是复用

来源: 责编: 时间:2024-06-14 08:52:26 200观看
导读一个线程池中的线程异常了,那么线程池会怎么处理这个线程?需要说明,本文的线程池都是java.util.concurrent.ExecutorService线程池,本文将围绕验证,阅读源码俩方面来解析这个问题。代码验证验证execute提交线程池中测试代

R9s28资讯网——每日最新资讯28at.com

一个线程池中的线程异常了,那么线程池会怎么处理这个线程?R9s28资讯网——每日最新资讯28at.com

R9s28资讯网——每日最新资讯28at.com

R9s28资讯网——每日最新资讯28at.com

需要说明,本文的线程池都是java.util.concurrent.ExecutorService线程池,本文将围绕验证,阅读源码俩方面来解析这个问题。R9s28资讯网——每日最新资讯28at.com

R9s28资讯网——每日最新资讯28at.com

代码验证

验证execute提交线程池中

测试代码:R9s28资讯网——每日最新资讯28at.com

public class ThreadPoolExecutorDeadTest {    public static void main(String[] args) throws InterruptedException {        ExecutorService executorService = buildThreadPoolExecutor();        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute-exception"));        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));        Thread.sleep(5000);        System.out.println("再次执行任务=======================");        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));        executorService.execute(() -> exeTask("execute"));    }    public static ExecutorService buildThreadPoolExecutor() {        return new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS,                new LinkedBlockingQueue<>(1000), new ThreadFactoryBuilder().setNameFormat("test-%s").build()                , new ThreadPoolExecutor.CallerRunsPolicy());    }    private static void exeTask(String name) {        String printStr = "[thread-name:" + Thread.currentThread().getName() + ",执行方式:" + name + "]";        if ("execute-exception".equals(name)) {            throw new RuntimeException(printStr + ", 我抛异常了");        } else {            System.out.println(printStr);        }    }}

执行结果如下:R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

结论:R9s28资讯网——每日最新资讯28at.com

execute 提交到线程池的方式,如果执行中抛出异常,并且没有在执行逻辑中catch,那么会抛出异常,并且移除抛出异常的线程,创建新的线程放入到线程池中。R9s28资讯网——每日最新资讯28at.com

验证submit提交线程池中

测试代码:R9s28资讯网——每日最新资讯28at.com

public class ThreadPoolExecutorDeadTest {    public static void main(String[] args) throws InterruptedException {        ExecutorService executorService = buildThreadPoolExecutor();        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute-exception"));        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));        Thread.sleep(5000);        System.out.println("再次执行任务=======================");        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));        executorService.submit(() -> exeTask("execute"));    }    public static ExecutorService buildThreadPoolExecutor() {        return new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS,                new LinkedBlockingQueue<>(1000), new ThreadFactoryBuilder().setNameFormat("test-%s").build()                , new ThreadPoolExecutor.CallerRunsPolicy());    }    private static void exeTask(String name) {        String printStr = "[thread-name:" + Thread.currentThread().getName() + ",执行方式:" + name + "]";        if ("execute-exception".equals(name)) {            throw new RuntimeException(printStr + ", 我抛异常了");        } else {            System.out.println(printStr);        }    }}

执行结果如下:R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

结论:R9s28资讯网——每日最新资讯28at.com

submit 提交到线程池的方式,如果执行中抛出异常,并且没有catch,不会抛出异常,不会创建新的线程。R9s28资讯网——每日最新资讯28at.com

源码解析

1.java.util.concurrent.AbstractExecutorService#submit(java.lang.Runnable);R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

2. 查看execute方法的执行逻辑;R9s28资讯网——每日最新资讯28at.com

R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

3. java.util.concurrent.ThreadPoolExecutor#processWorkerExit;R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

可以发现,如果抛出异常,会移除抛出异常的线程,创建新的线程。R9s28资讯网——每日最新资讯28at.com

4. 为什么submit方法,没有创建新的线程,而是继续复用原线程;R9s28资讯网——每日最新资讯28at.com

还记得,我们在3.1的时候,发现submit也是调用了execute方法,但是在调用之前,包装了一层 RunnableFuture,那一定是在RunnableFuture的实现 FutureTask中有特殊处理了,我们查看源码可以发现。R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

图片图片R9s28资讯网——每日最新资讯28at.com

但是,我们通过java.util.concurrent.FutureTask#get()就可以获取对应的异常信息。R9s28资讯网——每日最新资讯28at.com

R9s28资讯网——每日最新资讯28at.com

总结

当一个线程池里面的线程异常后:R9s28资讯网——每日最新资讯28at.com

  • 当执行方式是execute时,可以看到堆栈异常的输出,线程池会把这个线程移除掉,并创建一个新的线程放到线程池中。
  • 当执行方式是submit时,堆栈异常没有输出。但是调用Future.get()方法时,可以捕获到异常,不会把这个线程移除掉,也不会创建新的线程放入到线程池中。

以上俩种执行方式,都不会影响线程池里面其他线程的正常执行。R9s28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-93697-0.htmlJava线程池中线程异常后:是销毁还是复用

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 大厂面试必备:如何轻松实现分布式Session管理?

下一篇: Go必知必会:数组和切片详解

标签:
  • 热门焦点
  • 一加首款折叠屏!一加Open渲染图出炉:罕见单手可握小尺寸

    8月5日消息,此前就有爆料称,一加首款折叠屏手机将会在第三季度上市,如今随着时间临近,新机的各种消息也开始浮出水面。据悉,这款新机将会被命名为&ldquo;On
  • 从 Pulsar Client 的原理到它的监控面板

    背景前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,
  • 深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析

    在 Elasticsearch 中,function_score 可以让我们在查询的同时对搜索结果进行自定义评分。function_score 提供了一系列的参数和函数让我们可以根据需求灵活地进行设置。近期
  • 得物宠物生意「狂飙」,发力“它经济”

    作者|花花小萌主近日,得物宣布正式上线宠物鉴别,通过得物App内的&ldquo;在线鉴别&rdquo;,可找到鉴别宠物的选项。通过上传自家宠物的部位细节,就能收获拥有专业资质认证的得物鉴
  • 腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 阿里大调整

    来源:产品刘有媒体报道称,近期淘宝天猫集团启动了近年来最大的人力制度改革,涉及员工绩效、层级体系等多个核心事项,目前已形成一个初步的&ldquo;征求意见版&rdquo;:1、取消P序列
  • 认真聊聊东方甄选:如何告别低垂的果实

    来源:山核桃作者:财经无忌爆火一年后,俞敏洪和他的东方甄选依旧是颇受外界关心的&ldquo;网红&rdquo;。7月5日至9日,为期5天的东方甄选&ldquo;甘肃行&rdquo;首次在自有App内直播,
  • iQOO 11S评测:行业唯一的200W标准版旗舰

    【Techweb评测】去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,该机不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞
  • iQOO Neo8 Pro即将开售:到手价3099元起 安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
Top