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

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

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

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

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

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

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

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

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

代码验证

验证execute提交线程池中

测试代码:ow628资讯网——每日最新资讯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);        }    }}

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

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

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

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

验证submit提交线程池中

测试代码:ow628资讯网——每日最新资讯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);        }    }}

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

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

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

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

源码解析

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

总结

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

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

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

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

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

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

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

标签:
  • 热门焦点
  • 一加Ace2 Pro真机揭晓 钛空灰配色质感拉满

    终于,在经过了几波预热之后,一加Ace2 Pro的外观真机图在网上出现了。还是博主数码闲聊站曝光的,这次的外观设计还是延续了一加11的方案,只是细节上有了调整,例如新加入了钛空灰
  • 6月iOS设备好评榜:第一蝉联榜首近一年

    作为安兔兔各种榜单里变化最小的那个,2023年6月的iOS好评榜和上个月相比没有任何排名上的变化,仅仅是部分设备好评率的下降,长年累月的用户评价和逐渐退出市场的老款机器让这
  • CSS单标签实现转转logo

    转转品牌升级后更新了全新的Logo,今天我们用纯CSS来实现转转的新Logo,为了有一定的挑战性,这里我们只使用一个标签实现,将最大化的使用CSS能力完成Logo的绘制与动画效果。新logo
  • Golang 中的 io 包详解:组合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是对Reader和Writer接口的组合,
  • 如何通过Python线程池实现异步编程?

    线程池的概念和基本原理线程池是一种并发处理机制,它可以在程序启动时创建一组线程,并将它们置于等待任务的状态。当任务到达时,线程池中的某个线程会被唤醒并执行任务,执行完任
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz&ldquo;难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?&rdquo;这一番话,出自百合网联合创
  • 腾讯VS网易,最卷游戏暑期档,谁能笑到最后?

    作者:无锈钵来源:财经无忌7月16日晚,上海1862时尚艺术中心。伴随着幻象的精准命中,硕大的荧幕之上,比分被定格在了14:12,被寄予厚望的EDG战队以绝对的优势战胜了BLG战队,拿下了总决
  • 四年持续更迭坚持探索行业无人之境,HarmonyOS 4带来五大升级多项创新

    除了华为每年新发布的旗舰手机系列,上亿花粉更加期待鸿蒙系统每次的跨版本大更新。8月4日,HarmonyOS 4于HDC 2023正式发布,这也是该系统历经四年的再
Top