掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
哈嘍,大家好,我是了不起。

為溧水等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及溧水網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站制作、成都網(wǎng)站制作、溧水網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
我們?cè)谌粘i_發(fā)中,經(jīng)常跟多線程打交道,Spring 為我們提供了一個(gè)線程池方便我們開發(fā),它就是 ThreadPoolTaskExecutor ,接下來我們就來聊聊 Spring 的線程池吧。
SpringBoot 提供了注解 @Async 來使用線程池, 具體使用方法如下:
下面是一個(gè)簡單的例子:
@Component
@EnableAsync
@EnableScheduling
public class ScheduleTask {
@Async
@Scheduled(fixedRate = 2000)
public void testAsync1() {
try {
Thread.sleep(6000);
System.out.println(LocalDateTime.now() + "--線程1:" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async
@Scheduled(cron = "*/2 * * * * ?")
public void testAsync2() {
try {
Thread.sleep(1000);
System.out.println(LocalDateTime.now() + "--線程2:" + Thread.currentThread().getName());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}啟動(dòng)項(xiàng)目,得到如下日志結(jié)果:
圖片
可以發(fā)現(xiàn)在當(dāng)前環(huán)境下 task-${id} 這個(gè) id 并不是一直增長的,而是一直在復(fù)用 1-8。這個(gè)時(shí)候可能就會(huì)有的小伙伴們會(huì)比較好奇,默認(rèn)的不是 SimpleAsyncTaskExecutor 嗎?為什么從日志打印的效果上看像是一直在復(fù)用 8 個(gè)線程,難道用的是 ThreadPoolTaskExecutor?
原因是 SpringBoot2.1.0 版本后,新增了 TaskExecutionAutoConfiguration 配置類。其中聲明的默認(rèn)線程池就是 ThreadPoolTaskExecutor 。而 @Async 在選擇執(zhí)行器的時(shí)候會(huì)先去 IOC 容器中先找是否有 TaskExecutor 的 Bean對(duì)象,所以在當(dāng)前版本 SpringBoot 中,@Async 的默認(rèn) TaskExecutor 是 ThreadPoolTaskExecutor。
在 SpringBoot 項(xiàng)目中,我們可以在 yaml 或者 properties 配置文件中配置,或者使用 @Configuration 配置,下面演示配置方法。
# 核心線程池?cái)?shù)
spring.task.execution.pool.core-size=5
# 最大線程池?cái)?shù)
spring.task.execution.pool.max-size=10
# 任務(wù)隊(duì)列的容量
spring.task.execution.pool.queue-capacity=5
# 非核心線程的存活時(shí)間
spring.task.execution.pool.keep-alive=60
# 線程池的前綴名稱
spring.task.execution.thread-name-prefix=test-task-@Bean(name = "myThreadPoolTaskExecutor")
public ThreadPoolTaskExecutor getMyThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
int i = Runtime.getRuntime().availableProcessors();
taskExecutor.setCorePoolSize(i * 2);
taskExecutor.setMaxPoolSize(i * 2);
taskExecutor.setQueueCapacity(i * 2 * 100);
taskExecutor.setKeepAliveSeconds(60);
taskExecutor.setThreadNamePrefix("my-task-");
taskExecutor.initialize();
return taskExecutor;
}RejectedExectutionHandler 參數(shù)字段用于配置絕策略,常用拒絕策略如下
上面簡單介紹了 Spring 自帶的線程池 ThreadPoolTaskExecutor 的配置和使用,并且講了線程池的參數(shù)和處理流程。當(dāng)然Spring提供了7個(gè)線程池的實(shí)現(xiàn),感興趣的可以自行了解~

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流