ThreadPoolTaskExecutor和ThreadPoolExecutor区别

ThreadPoolTaskExecutor和ThreadPoolExecutor区别之前工作中发现有同事在使用线程池的时候经常搞混淆ThreadPoolTaskExecutor和ThreadPoolExecutor,座椅在这里想写一片博客来讲讲这两个线程池的区别以及使用ThreadPoolExecutor这个类是JDK中的线程池类,继承自Executor,Executor顾名思义是专门用来处理多线程相关的一个接口,所有县城相关的类都实现了这个接口,相关的继承实现类图如下…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

之前工作中发现有同事在使用线程池的时候经常搞混淆ThreadPoolTaskExecutor和ThreadPoolExecutor,座椅在这里想写一片博客来讲讲这两个线程池的区别以及使用

  1. ThreadPoolExecutor

这个类是JDK中的线程池类,继承自Executor, Executor 顾名思义是专门用来处理多线程相关的一个接口,所有县城相关的类都实现了这个接口,里面有一个execute()方法,用来执行线程,线程池主要提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁的额外开销,提高了响应的速度。相关的继承实现类图如下。

ThreadPoolTaskExecutor和ThreadPoolExecutor区别

一、线程池接口:ExecutorService为线程池接口,提供了线程池生命周期方法,继承自Executor接口,ThreadPoolExecutor为线程池实现类,提供了线程池的维护操作等相关方法,继承自AbstractExecutorService,AbstractExecutorService实现了ExecutorService接口。

二、线程池的体系结构:
java.util.concurrent.Executor 负责线程的使用和调度的根接口
        |–ExecutorService 子接口: 线程池的主要接口
                |–ThreadPoolExecutor 线程池的实现类
                |–ScheduledExceutorService 子接口: 负责线程的调度
                    |–ScheduledThreadPoolExecutor : 继承ThreadPoolExecutor,实现了ScheduledExecutorService
            

三、工具类 : Executors

Executors为线程迟工具类,相当于一个工厂类,用来创建合适的线程池,返回ExecutorService类型的线程池。有人如下方法。
ExecutorService newFixedThreadPool() : 创建固定大小的线程池
ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
ExecutorService newSingleThreadExecutor() : 创建单个线程池。 线程池中只有一个线程

ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务

其中AbstractExecutorService是他的抽象父类,继承自ExecutorService,ExecutorService 接口扩展Executor接口,增加了生命周期方法。

实际应用中我一般都比较喜欢使用Exectuors工厂类来创建线程池,里面有五个方法,分别创建不同的线程池,如上,创建一个制定大小的线程池,Exectuors工厂实际上就是调用的ExectuorPoolService的构造方法,传入默认参数。

public class Executors {

    /**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * {@code nThreads} threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if {@code nThreads <= 0}
     */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

    /**
     * Creates a thread pool that maintains enough threads to support
     * the given parallelism level, and may use multiple queues to
     * reduce contention. The parallelism level corresponds to the
     * maximum number of threads actively engaged in, or available to
     * engage in, task processing. The actual number of threads may
     * grow and shrink dynamically. A work-stealing pool makes no
     * guarantees about the order in which submitted tasks are
     * executed.
     *
     * @param parallelism the targeted parallelism level
     * @return the newly created thread pool
     * @throws IllegalArgumentException if {@code parallelism <= 0}
     * @since 1.8
     */
    public static ExecutorService newWorkStealingPool(int parallelism) {
        return new ForkJoinPool
            (parallelism,
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
    }

当然,我们也可以直接new ThreadPoolExecutor的构造方法来创建线程池,传入需要的参数。

2.ThreadPoolTaskExecutor

这个类则是spring包下的,是sring为我们提供的线程池类,这里重点讲解这个类的用法,可以使用基于xml配置的方式创建

<!-- spring线程池 -->
    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 核心线程数  -->
        <property name="corePoolSize" value="10"/>
        <!-- 最大线程数 -->
        <property name="maxPoolSize" value="200"/>
        <!-- 队列最大长度 >=mainExecutor.maxSize -->
        <property name="queueCapacity" value="10"/>
        <!-- 线程池维护线程所允许的空闲时间 -->
        <property name="keepAliveSeconds" value="20"/>
        <!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
        </property>
    </bean>

然后通过自动注入的方式注入线程池,

@Resource(name="taskExecutor")
ThreadPoolTaskExecutor taskExecutor;
// 或者可以直接@Autowried
@AutoWired
ThreadPoolTaskExecutor taskExecutor

或者是通过配置类的方式配置线程池,然后注入。

@Configuration
public class ExecturConfig {
    @Bean("taskExector")
    public Executor taskExector() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int i = Runtime.getRuntime().availableProcessors();//获取到服务器的cpu内核
        executor.setCorePoolSize(5);//核心池大小
        executor.setMaxPoolSize(100);//最大线程数
        executor.setQueueCapacity(1000);//队列程度
        executor.setKeepAliveSeconds(1000);//线程空闲时间
        executor.setThreadNamePrefix("tsak-asyn");//线程前缀名称
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//配置拒绝策略
        return executor;
    }

上面注解中已经注释了参数的详解,这里重点讲解一下spring线程池的拒绝策略和处理流程。

  • 拒绝策略

rejectedExectutionHandler参数字段用于配置绝策略,常用拒绝策略如下

AbortPolicy:用于被拒绝任务的处理程序,它将抛出RejectedExecutionException

CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务。

DiscardOldestPolicy:用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute。

DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。

  • 处理流程

1.查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第二步。

2.查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第三步。

3.查看线程池是否已满,即就是是否达到最大线程池数,不满就创建一条线程执行任务,否则就按照策略处理无法执行的任务。

流程图如下

 

ThreadPoolTaskExecutor和ThreadPoolExecutor区别

总结:本篇文章主要讲了一下JDK线程池和spring线程池这两个线程池,具体实际业务则和平时使用一样。下一篇文章将讲一下如何使用spring的异步多线程调用注解@Async使用。springboot中@Async多线程注解使用

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158295.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 整合Druid—SpringBoot[通俗易懂]

    整合Druid—SpringBoot[通俗易懂]整合Druid(数据源)Druid简介Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了C3P0、DBCP等DB池的优点,同时加入了日志监控。Druid可以很好的监控DB池连接和SQL的执行情况,天生就是针对监控而生的DB连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。SpringBoot2.0以上默认使用Hikari

    2022年7月23日
    9
  • ANT安装(亲测可用)「建议收藏」

    ANT安装(亲测可用)「建议收藏」ANT在win10x64系统上进行安装,安装步骤如下。1、打开官网2、选择要下载版本3、配置环境变量在path里配置ant安装地址\binant安装地址\lib4、在cmd里验证:Linux上安装ANT:1、下载apache-ant-1.10.5-bin.tar.gz到home目录2、cpapache-ant-1.10.5-bin.tar.gz/usr/local3、cd/usr/local4、tar-zxvfapache-ant-1.10.5-bin.ta

    2022年7月18日
    14
  • 项目打成Jar包和War包的介绍与区别

    项目打成Jar包和War包的介绍与区别1.jar包的介绍JAR(JavaArchive,Java归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。JavaSE程序可以打包成Jar包(J其实可以理解为Java了)。JAR文件格式以流行的ZIP文件格式为基础。与ZIP文件不同的是,JAR文件不仅用于压缩和发布,而且还用于部署和封装库、组件和插件程序,并可被像编译器和JVM这样的工具直接使用…

    2022年5月23日
    35
  • 实验:ospf与BFD联动实验(EVE模拟器-Cisco)「建议收藏」

    实验:ospf与BFD联动实验(EVE模拟器-Cisco)「建议收藏」一、实验拓扑二、实验要求请完成以下需求:1、设备互联地址如拓扑所示;2、R1与R2、R2与R4、R1与R4之间运行OSPF,互联地址建邻,协议号123;3、配置bfd与ospf联动,并观察其bfd配置之后有何效果。三、实验配置过程1、配置AR1、2、3的IP地址AR1:hostnameAR1//修改名称interfaceGigabitEthernet0/0//进入接口ipaddress20.0.0.1255.255.255.0//配置IPAR2:hostname

    2022年5月3日
    58
  • 树莓派 1602A显示屏[通俗易懂]

    树莓派 1602A显示屏[通俗易懂]树莓派1602A显示屏下面代码本人测试过没有问题,开始运行完屏幕上什么也没有显示出来,后来调整了下电位器可以了,所以大家如果按着下面的做出来之后运行什么也没有显示的话,记得调整下电位器[img]http://dl2.iteye.com/upload/attachment/0128/7783/cefa073e-97ee-3d45-bddf-d7a878c232a1.png[/img…

    2022年9月22日
    0
  • FTP测试工具类「建议收藏」

    FTP测试工具类「建议收藏」因项目现场无法部署IDE工具联调FTP服务器,开发个简单的小工具,打成jar部署联调测。一下是该工具的源代码。packagecn.org.july.ftp;importorg.apache.commons.net.ftp.FTPClient;importorg.apache.commons.net.ftp.FTPFile;importorg.apache.commons.net….

    2022年5月6日
    94

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号