当我们需要实现并发、异步等操作时,通常都会使用到ThreadPoolTaskExecutor,现对其使用稍作总结。

配置
ThreadPoolTaskExecutor通常通过XML方式配置,或者通过Executors的工厂方法进行配置。
XML方式配置代码如下:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="8"/> <!--核心线程数 -->
<property name="maxPoolSize" value="16"/> <!--最大线程数 -->
<property name="keepAliveSeconds" value ="3000"/> <!--线程最大空闲时间 -->
<property name="queueCapacity" value="200"/> <!-- 队列大小 -->
<property name="threadNamePrefix" value="TASK_EXECUTOR"/>
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy"/>
</property>
</bean>

rejectedExecutionHandler字段用于配置拒绝策略,常用的拒绝策略如下:

AbortPolicy,用于被拒绝任务的处理程序,它将抛出RejectedExecutionException。
CallerRunsPolicy,用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务。
DiscardOldestPolicy,用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute。
DiscardPolicy,用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。
其他说明:

为了实现某些特殊的业务需求,用户可以选择使用自定义策略,只需实现RejectedExecutionHandler接口即可。
建议配置threadNamePrefix属性,出问题时可以更方便的进行排查。
提交任务
无返回值的任务使用execute(Runnable)
有返回值的任务使用submit(Runnable)
处理流程
当一个任务被提交到线程池时,首先查看线程池的核心线程是否都在执行任务,否就选择一条线程执行任务,是就执行第二步。
查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第三步。
查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第四步。
查看线程池是否已满,不满就创建一条线程执行任务,否则就按照策略处理无法执行的任务。
在ThreadPoolExecutor中表现为:

如果当前运行的线程数小于corePoolSize,那么就创建线程来执行任务(执行时需要获取全局锁)。
如果运行的线程大于或等于corePoolSize,那么就把task加入BlockQueue。
如果创建的线程数量大于BlockQueue的最大容量,那么创建新线程来执行该任务。
如果创建线程导致当前运行的线程数超过maximumPoolSize,就根据饱和策略来拒绝该任务。
关闭线程池
调用shutdown或者shutdownNow,两者都不会接受新的任务,而且通过调用要停止线程的interrupt方法来中断线程,有可能线程永远不会被中断,不同之处在于shutdownNow会首先将线程池的状态设置为STOP,然后尝试停止所有线程(有可能导致部分任务没有执行完)然后返回未执行任务的列表。而shutdown则只是将线程池的状态设置为shutdown,然后中断所有没有执行任务的线程,并将剩余的任务执行完。

配置线程个数
如果是CPU密集型任务,那么线程池的线程个数应该尽量少一些,一般为CPU的个数+1条线程。
如果是IO密集型任务,那么线程池的线程可以放的很大,如2*CPU的个数。
对于混合型任务,如果可以拆分的话,通过拆分成CPU密集型和IO密集型两种来提高执行效率;如果不能拆分的的话就可以根据实际情况来调整线程池中线程的个数。
监控线程池状态
常用状态:

taskCount:线程需要执行的任务个数。
completedTaskCount:线程池在运行过程中已完成的任务数。
largestPoolSize:线程池曾经创建过的最大线程数量。
getPoolSize获取当前线程池的线程数量。
getActiveCount:获取活动的线程的数量
通过继承线程池,重写beforeExecute,afterExecute和terminated方法来在线程执行任务前,线程执行任务结束,和线程终结前获取线程的运行情况,根据具体情况调整线程池的线程数量。

参考来源:

[1] https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html
---------------------
作者:楚兴
来源:CSDN
原文:https://blog.csdn.net/foreverling/article/details/78073105?utm_source=copy

版权声明:本文为博主原创文章,转载请附上博文链接!

ThreadPoolTaskExecutor使用详解的更多相关文章

  1. ThreadPoolTaskExecutor使用详解(转)

    当并发或者异步操作,都会用到ThreadPoolTaskExecutor.现在对线程池稍作理解. /*** *@Auth dzb *@Date 22:29 2018/8/29 *@Descriptio ...

  2. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  3. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  4. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  5. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  6. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  7. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  8. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  9. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

随机推荐

  1. spring+hibernate单元测试案例

    1,maven创建web工程 2,导入相关依赖 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmln ...

  2. Nexus Repository OSS 3安装配置使用

    Nexus Repository OSS 3是一个开源的仓库管理系统,提供了更加丰富的功能,而且安装.配置.使用起来也更加简单方便.OSS 3版本主要支持的仓库(Repository)包括如下: bo ...

  3. 【Unity优化】Unity中究竟能不能使用foreach?

    关于这个话题,网络上讨论的很多,我也收集了一些资料,都不是很齐全,所以自己亲自测试,这里把结果分享给大家. foreach究竟怎么了? 研究过这个问题的人都应该知道,就是它会引起频繁的GC Alloc ...

  4. HBuilder打包app(vue项目)

    一.测试项目是否可以正确运行    指令:npm run dev 首先我们先建立一个vue的项目,本人用的是vue-cli随便建立的,然后运行项目 不必非得是像我这样的,这一步的目的只是测试一下咱们的 ...

  5. MyView.java 自己画的view

    package myapplication21.lum.com.mycanvas; import android.content.Context;import android.graphics.Can ...

  6. Java多线程常用写法,使用匿名内部类

    匿名内部类是基于抽象类和接口而言的. //匿名内部类(解决定义过多文件的问题,标准开发一个类就是一个文件) // new Runnable() { // @Override // public voi ...

  7. Jsoup获取DOM元素

    (1)doc.getElementsByTag(String tagName); (2)doc.getElementById(String id); (3)doc.getElementsByClass ...

  8. CAS 认证

    Central Authentication Service http session 保持机制 1.  用户向服务端发送密码,服务端生成与用户对应的 sessionid 2. 服务端将这个 sess ...

  9. git清空远程仓库

    需求背景:因为用jenkins连接了git仓库,有时候job构建出现问题,需要排查问题,但是呢,真实的项目代码量非常pang大,所以就需要建1个测试仓库,使用最少量的代码能复现自己的问题就好. 这就需 ...

  10. java web项目启动加载顺序

    转载:https://www.cnblogs.com/writeLessDoMore/p/6935524.html web.xml加载过程(步骤):       1.启动WEB项目的时候,容器(如:T ...