線程池就是首先創(chuàng)建一些線程,它們的集合稱為線程池弃锐。使用線程池可以很好地提高性能,線程池在系統(tǒng)啟動時即創(chuàng)建大量空閑的線程霹菊,程序將一個任務傳給線程池旋廷,線程池就會啟動一條線程來執(zhí)行這個任務饶碘,執(zhí)行結束以后,該線程并不會死亡扎运,而是再次返回線程池中成為空閑狀態(tài),等待執(zhí)行下一個任務豪治。
四種常用的線程池
- Executors.newCacheThreadPool():可緩存線程池
- Executors.newFixedThreadPool(int n):創(chuàng)建一個可重用固定個數的線程池负拟,以共享的無界隊列方式來運行這些線程。
- Executors.newScheduledThreadPool(int n):創(chuàng)建一個定長線程池花吟,支持定時及周期性任務執(zhí)行
- Executors.newSingleThreadExecutor():創(chuàng)建一個單線程化的線程池厨姚,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行谬墙。
spring-boot 新建自定義線程池
我們的需要新建一個Configuration 類來配置我們的線程池參數芭梯。
package com.uhi.applyment4sub.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author adoreFT
* @date 2021/01/13 16:19
* @Description: uhi線程池配置類
*/
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
/**
* 默認情況下,在創(chuàng)建了線程池后玖喘,線程池中的線程數為0累奈,當有任務來之后,就會創(chuàng)建一個線程去執(zhí)行任務搞乏,
* 當線程池中的線程數目達到corePoolSize后,就會把到達的任務放到緩存隊列當中请敦;
* 當隊列滿了,就繼續(xù)創(chuàng)建線程侍筛,當線程數量大于等于maxPoolSize后匣椰,開始使用拒絕策略拒絕
*/
/**
* 核心線程數(默認線程數)
*/
private static final int corePoolSize = 5;
/**
* 最大線程數
*/
private static final int maxPoolSize = 30;
/**
* 允許線程空閑時間(單位:默認為秒)
*/
private static final int keepAliveTime = 30;
/**
* 緩沖隊列大小
*/
private static final int queueCapacity = 10000;
/**
* 線程池名前綴
*/
private static final String threadNamePrefix = "hdl-uhi-service-";
@Bean("taskExecutor") // bean的名稱,默認為首字母小寫的方法名
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 線程池對拒絕任務的處理策略
// CallerRunsPolicy:由調用線程(提交任務的線程)處理該任務
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
executor.initialize();
return executor;
}
}
其中我們的靜態(tài)參數也可以放在配置文件中入录,我這邊使用的 yml 配置文件:
#線程池配置參數
task:
pool:
corePoolSize: 5 #設置核心線程數
maxPoolSize: 20 #設置最大線程數
keepAliveSeconds: 300 #設置線程活躍時間(秒)
queueCapacity: 50 #設置隊列容量
上邊的這里需要用注解來引用對象方式實現:
@ConfigurationProperties(prefix = "task.pool")
注解解釋
@Configuration用于定義配置類佳镜,被注解的類內部包含有一個或多個被@Bean注解的方法邀杏,這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進行掃描,并用于構建bean定義望蜡,初始化Spring容器。
@EnableAsync開始對異步任務的支持
@Async 定義一個線程任務
@Bean 產生一個Bean對象谢肾,然后這個Bean對象交給Spring管理 (如上:@Bean("taskExecutor"))
線程使用
- 引用線程池
@Autowired
@Qualifier(value = "taskExecutor")
private ThreadPoolTaskExecutor poolTaskExecutor;
- 異步方法定義
//根據組織做數據更新以及新增刪除
for (UhiDdOrgContrast orgContrast : orgContrastList) {
poolTaskExecutor.execute(() -> {
userPackAgeData(token, orgContrast);
});
}
userPackAgeData 方法添加指定線程名:
@Async("taskExecutor")
public void userPackAgeData(String token, UhiDdOrgContrast orgContrast) {
//業(yè)務代碼實現
// XXXX
}