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多线程注解使用

 

 

 

 

 

 

 

 

 

 

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • WPF教程2013新版「建议收藏」

    视频目录:(一)WPF基础:控件模型、XAML基础、基础控件【.Net培训—第三季WPF教程】001-课程说明【.Net培训—第三季WPF教程】002-VisualStudio下WPF开发环境的基本使用.zip【.Net培训—第三季WPF教程】003-sender是什么.zip【.Net培训—第三季WPF教程】004-复习继承和类型转换.zip【.Net培训—第三季WPF教程】005-集…

  • 正在接入或无法接入认证服务器(服务器未运行怎么解决)

    迷你版云服务器未启动内容精选换一换企业主机安全(HostSecurityService,HSS)是提升服务器整体安全性的服务,通过主机管理、风险防御、入侵检测、安全运营、网页防篡改功能,可全面识别并管理云服务器中的信息资产,实时监测云服务器中的风险,降低服务器被入侵的风险。使用主机安全需要在云服务器中安装Agent。安装Agent后,您的云服务器将受到HSS云端防护中企业主机安全(Host…

  • Vue(2)计数器的实现「建议收藏」

    Vue(2)计数器的实现「建议收藏」计数器的实现在页面上简单实现一个计数器<!DOCTYPEhtml><htmllang="en"><head><metach

  • zipfile模块使用「建议收藏」

    zipfile模块使用「建议收藏」zipfile模块zipfile说明zipfile的常用方法:is_zipfile():ZipFile类的常用方法:ZipFile():ZipFile.close():ZipFile.getinfo(),ZipFile.infolist()和ZipFile.namelist()ZipFile.extract()和ZipFile.extractall()ZipFile.printdir()和ZipFile.read()ZipFile.write()和ZipFile.writestr():ZipInfo类的常用

  • SQLServer2008R2密钥「建议收藏」

    SQLServer2008R2密钥:Developer:PTTFM-X467G-P7RH2-3Q6CG-4DMYBEnterprise:JD8Y6-HQG69-P9H84-XDTPG-34MBBMicrosoftSQLServer2008R2序列号密钥开发版32位:MC46H-JQR3C-2JRHY-XYRKY-QWPVM开发版64位:FTMGC-B2J97-PJ4QG-…

  • kvm虚拟机xml文件在哪里_爱快kvm虚拟机

    kvm虚拟机xml文件在哪里_爱快kvm虚拟机virshxml创建kvm虚拟机准备工作sudoapt-getupdatesudoapt-getinstallqemu-kvmsudoapt-getinstallvnc4serversudoapt-getinstallbridge-utils增加网卡内容如下:root@zhangji16vm:/home/prj1#cat/etc/network/in…

发表回复

您的电子邮箱地址不会被公开。

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