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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 利用远程外网服务器搭建代理服务器[通俗易懂]

    利用远程外网服务器搭建代理服务器[通俗易懂]安装CCProxy官网地址:http://www.ccproxy.com/下载安装即可,软件使用很简单。配置CCProxy配置端口基本上不需要配置什么,只要你将默认的端口改为你的端口号就行,不改可能会被其他软件扫描到。新增账号新增账号支持访问,具体权限可以看说明。选择你的远程服务器特别说明:你的服务器一定要配置安全组,否则端口无法访问。通过服务器中的teln…

    2022年5月1日
    165
  • 在c语言里0和1表示什么_’0’是什么意思c语言

    在c语言里0和1表示什么_’0’是什么意思c语言C语言中常见~Number,怎么计算?计算一个数字的~number比如说现在有A=60那么A的8位二进制数就是00111100那首先要计算~A即~60,那么先取反即11000011。因为负数的补码是取反+1。所以此处逆向操作需要-1取反即11000011-1==11000010(第一步逆向操作)11000010=>取反=>00111101=>十进制的61最后结果A==60,~A=-61C

    2022年9月20日
    1
  • 解决:VUE同一路由强制刷新页面

    解决:VUE同一路由强制刷新页面解决:VUE同一路由强制刷新页面

    2022年7月11日
    67
  • python激活码2021_通用破解码[通俗易懂]

    python激活码2021_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
    1.0K
  • html表格空格符是什么,HTML中的空格符号是什么

    html表格空格符是什么,HTML中的空格符号是什么在HTML中的空格符号有:表示不断行的空白; 表示半个空白; 表示一个空白等在平时我们写文章时遇到空格时都会直接输入空格键来达到空格的效果,但是在HTML代码中如果我们输入空格键就会被忽略,达不到空格的效果,今天就像大家介绍HTML中空格代码如何写,希望对大家有所帮助。【推荐课程:HTML课程】方法是HTML空格转义字符,当我们需要几个空白字符时就输入几个例Gxl网提供大量免费、原创、…

    2022年10月4日
    0
  • Pytest(11)allure报告[通俗易懂]

    Pytest(11)allure报告[通俗易懂]前言allure是一个report框架,支持java的Junit/testng等框架,当然也可以支持python的pytest框架,也可以集成到Jenkins上展示高大上的报告界面。mac环境:

    2022年7月29日
    3

发表回复

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

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