首页 > 其他分享 >ThreadPoolExecutor线程池解析

ThreadPoolExecutor线程池解析

时间:2024-04-11 11:26:32浏览次数:25  
标签:execute submit 线程 executor new 解析 ThreadPoolExecutor

ThreadPoolExecutor线程池解析

一、ThreadPoolExecutor常见参数

jdk中Executors提供了几种常用的线程池,底层都是ThreadPoolExecutor。

    public ThreadPoolExecutor(int corePoolSize,//核心线程数
                              int maximumPoolSize,// 最大线程数
                              long keepAliveTime,//非核心线程空闲存活时间
                              TimeUnit unit,// 时间单位
                              BlockingQueue<Runnable> workQueue,// 工作队列
                              ThreadFactory threadFactory,//线程工厂
                              RejectedExecutionHandler handler //线程池拒绝策略
) {}

核心线程是正式工,最大线程数中除去这部分都是临时工(工作队列满了才用到),有活就干,没活就歇着,歇的时间长了就被干掉,工作队列中就是排好的活,当正式工和零时工都在干活,排期也排满了,就执行拒绝策略。

Pool

二、ThreadPoolExecutor线程池中异常捕获处理方案

submit可以提交Callable和Runnable两种类型的task,execute只能执行Runnable.
submit在执行task的时候,会将其封装成RunnableFuture,这样使得有返回结果,可以通过get获取返回值,但是在异常处理方面和execute会有区分。

1、submit、execute执行task出现异常

使用ThreadPoolExecutor提交任务时,submit、execute两种方式都可,但submit只是提交了任务,即使任务中出现异常,也不会有任何提示。

 @org.junit.jupiter.api.Test
void testF1() {

    ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());


    executor.submit(new Task());

    executor.execute(new Task());

    System.out.println("over");

}


class Task implements Runnable {

    @Override
    public void run() {

        int i = 1/0;
    }
}

结果 Exception in thread "pool-1-thread-2" java.lang.ArithmeticException: / by zero
submit提交任务都不会捕捉异常,在get才会得到异常。

 Future<?> future =executor.submit(new Task());
 future.get();

此时会抛出异常

2、异常处理

2.1 在task中try...catch
 @org.junit.jupiter.api.Test
    void testF1() throws ExecutionException, InterruptedException {
        List<String> list = Arrays.asList("hello", "world");

        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());


        executor.submit(new Task());

        executor.execute(new Task());

        System.out.println("over");

    }


    class Task implements Runnable {

        @Override
        public void run() {
            try {
                int i = 1/0;

            }catch (Exception e){
                System.out.println("异常");
            }
        }
    }

task会进入catch中

over 异常 异常

2.2使用Thread.setDefaultUncaughtExceptionHandler方法自定义ThreadFactory

通过自定义ThreadFactory中生产的Thread,线程池在execute方法中出发异常会执行setDefaultUncaughtExceptionHandler中定义的内容,同样对submit无效。

//1.实现一个自己的线程池工厂
ThreadFactory factory = (Runnable r) -> {
    //创建一个线程
    Thread t = new Thread(r);
    //给创建的线程设置UncaughtExceptionHandler对象 里面实现异常的默认逻辑
    t.setDefaultUncaughtExceptionHandler((Thread thread1, Throwable e) -> {
        System.out.println("线程工厂设置的exceptionHandler" + e.getMessage());
    });
    return t;
};


ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),factory);

executor.execute(new Task());// 线程工厂设置的exceptionHandler
executor.submit(new Task()); // 无反应
2.3 重写ThreadPoolExecutor的afterExecute方法

通过重写ThreadPoolExecutor的afterExecute方法,可以处理submit和execute异常,但是submit提交的需要加一步判断。

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>()) {

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        //默认捕获execute中的异常
        if (t != null) {
            System.out.println("afterExecute里面获取到excute提交的异常信息,处理异常" + t.getMessage());
        }
        //如果r的实际类型是FutureTask 那么是submit提交的,所以可以在里面get到异常
        if (r instanceof FutureTask) {
            try {
                Future<?> future = (Future<?>) r;
                //get获取异常
                future.get();

            } catch (Exception e) {
                System.out.println("afterExecute里面获取到submit提交的异常信息,处理异常" + e);
            }
        }
    }
};

executor.execute(new Task());//处理异常
executor.submit(new Task());//处理异常

标签:execute,submit,线程,executor,new,解析,ThreadPoolExecutor
From: https://www.cnblogs.com/cgl-dong/p/18128456

相关文章

  • 多线程知识点
     1.多线程基本概念1)概念:多线程简单来说是一个程序具备同时执行多个功能的能力。在多线程中,这些功能被称为线程,每个线程都有自己的执行路径,它们可以并行(xíng)运行,同时共享程序的资源与内存。而在传统的单线程程序中,代码会顺序执行,一个任务完成后才会开始下一个任......
  • 单线程Reactor模型
    1.如何理解reactorreactor是一种设计模式。用于处理事件驱动的系统。reactor模式,主要有两个组件:reactor反应器:负责监听所有事件,当事件发生时,调用相应的处理程序。reactor本身时一个事件循环,负责处理I/O事件。handler处理程序:处理特点类型的事件。当reactor接收......
  • 解析oracle的DDL语句生成高斯内表及表字段主键配置
    oracle的DDL语句如下:CREATETABLETPPROD.CONFIG( NOVARCHAR2(50), CONFIGCODEVARCHAR2(400), CONFIGVALUEVARCHAR2(400), CONSTRAINTPK_GUENDORASSISTCONFIGPRIMARYKEY(NO,CONFIGCODE));CREATEUNIQUEINDEXPK_GUENDORASSISTCONFIGONTPPROD.GUENDORASSI......
  • 多线程下写全局变量时,可借助sleep(0)让出cpu
    目录一个demo(对全局变量++)-->反汇编阅读cpu指令多个线程都去对全局变量++线程不挂起sleep(0)使线程挂起,让出cpu总结一下为啥不到10W?加锁版本近期在重读APUE,对unix下多线程有了新的理解用一个小demo来说明多线程下写全局变量时,让出cpu(使线程挂起)的重要性一个demo(对全局变量++)-......
  • 多线程(进阶篇&小白易懂版)
    文章目录多线程为什么要有多线程多线程案例线程通讯分传主线程通讯主传分关闭线程线程锁多线程概念:多线程就是多个线程同时工作的过程,我们可以将线程看作是程序的执行路径,每个线程都定义了一个独特的控制流,用来完成特定的任务。如果您的应用程序涉及到复杂且耗时的......
  • 2024年3月电子学会青少年软件编程 中小学生Python编程等级考试一级真题解析(判断题)
    2024年3月Python编程等级考试一级真题解析判断题(共10题,每题2分,共20分)26、turtle画布的坐标系原点是在画布的左上角答案:错考点分析:考查turtle相关知识,turtle画布坐标系是在画布的中点,答案错误27、Python变量名区分大小写,book和BOOK不是同一个变量答案:对考点分析:考查......
  • 用本小组项目中实际的例子来重现如下问题: 1、代码覆盖率对于“应该写但是没有写的代
    例子1-代码覆盖率无法检测资源管理问题:假设在移动充电桩应用中有一个负责与服务器通信的模块,它从服务器下载充电站的实时状态信息。开发者编写了一段代码来连接服务器、发送请求并接收响应数据,但是在处理完响应后,忘记关闭网络连接或释放相关资源:JavapublicclassChargingSta......
  • c++11实现线程池
    c++11实现线程池c++线程库thread创建线程和同步的方式jion,detach#include<iostream>#include<thread>voidprintf_hw(std::strings){ std::cout<<s<<"\n";}intmain(){ std::threada(printf_hw,"nihao"); //a.join();//同步 a.de......
  • Java8 Stream API全面解析——高效流式编程的秘诀
    文章目录什么是StreamApi?快速入门流的操作创建流中间操作filter过滤map数据转换flatMap合并流distinct去重sorted排序limit限流skip跳过peek操作终结操作forEach遍历forEachOrdered有序遍历count统计数量min最小值max最大值reduce聚合collect收集anyM......
  • 深入了解与全面解析华为认证(HCIA/HCIP/HCIE)
     一、网络行业技术认证网络行业对于技术评定一般分为两种,一种是企业认证,一种是国家认证企业认证属于技术认证,在国内的互联网企业都会承认,用于评定一个人的技术等级或者企业招投标的资质。网络行业认证最好的有三种,又分别有三种不同等级及多种方向,分别为:华为、思科、H3C(华......