Spring线程池的配置及使用ThreadPoolTaskExecutor过程
作者:Jason_520168
本文主要介绍了Spring提供的线程池ThreadPoolTaskExecutor及其配置方式,以及FixedThreadPool线程池的使用注意事项,同时强调了计数器的使用可以保证线程池执行顺序
一、ThreadPoolTaskExecutor是什么?
ThreadPoolTaskExecutor是Spring提供的线程池,通过配置参数初始化线程池,随取随用,不需要操作线程的创建和销毁。
二、代码实现
1.配置类ExecutorConfig
代码如下(示例):
@Configuration
@EnableAsync
public class ExecutorConfig {
private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
private int corePoolSize = 5;
private int maxPoolSize = 10;
private int queueCapacity = 99999;
private String namePrefix = "async-service-";
@Bean(name = "asyncServiceExecutor")
public ThreadPoolTaskExecutor asyncServiceExecutor(){
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
// rejection-policy: 当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS: 不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
2.引入使用
代码如下(示例):
@Resource(name = "asyncServiceExecutor")
private ThreadPoolTaskExecutor executor;
//定义计数器
final CountDownLatch countDownLatch=new CountDownLatch(list.size());
executor.execute(()-> {
try {
//Do something
} catch (Exception e) {
log.error(e.getMessage());
} finally {
log.info(Thread.currentThread().getName() + "执行完成");
//计数器减一
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
executor.shutdownNow();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Do something
三、FixedThreadPool线程池
我们在开发中经常会用到Java提供的工具类创建线程池,FixedThreadPool就是其中之一,但在使用中要注意这个线程池一旦开启会引起内存飙升的问题,下面我们来看下源码。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//定义计数器
final CountDownLatch countDownLatch=new CountDownLatch(list.size());
fixedThreadPool.execute(()-> {
try {
//Do something
} catch (Exception e) {
log.error(e.getMessage());
} finally {
log.info(Thread.currentThread().getName() + "执行完成");
//计数器减一
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
fixedThreadPool.shutdownNow();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Do something


上面两图是截图出来的源码,重点就在这个new出来的队列,通常称为无界队列,因为这个队列默认大小是Interger.MAX_VALUE,所以在线程池创建的一瞬间内存就会飙升,直到所有线程执行完毕,关闭线程池,才会释放内存
总结
注意:
- 计数器的定义是为了保证:线程池全部执行完for循环中的内容,再执行后续的内容。
- 如果不需要保证执行顺序,可以不使用计数器。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
