一、线程池基本配置
1.1 配置文件
#springboot线程池配置
task:
pool:
corePoolSize: 10
maxPoolSize: 20
keepAliveSeconds: 300
queueCapacity: 50
1.2 基本配置类
@Data
@Component
@ConfigurationProperties(prefix = "task.pool")
public class TaskThreadPoolConfig {
/** 核心线程数 */
private int corePoolSize;
/** 最大线程数 */
private int maxPoolSize;
/** 线程空闲时间 */
private int keepAliveSeconds;
/** 任务队列容量(阻塞队列) */
private int queueCapacity;
}
二、线程池配置
2.1 重写默认线程池
@Slf4j
@Component
@EnableAsync
public class OverrideDefaultThreadPoolConfig implements AsyncConfigurer {
@Autowired private TaskThreadPoolConfig config;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
// 最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
// 队列容量
executor.setQueueCapacity(config.getQueueCapacity());
// 活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
// 线程名字前缀
executor.setThreadNamePrefix("default-thread-");
/*
当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)
CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* 异步任务中异常处理
*
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> {
log.error("==========================" + ex.getMessage() + "=======================", ex);
log.error("exception method:" + method.getName());
};
}
2.2 创建自定义线程池
@Configuration
@EnableAsync
public class CustomizeThreadPoolConfig {
@Autowired private TaskThreadPoolConfig config;
@Bean("customizeThreadPool")
public Executor doConfigCustomizeThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
// 最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
// 队列容量
executor.setQueueCapacity(config.getQueueCapacity());
// 活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
// 线程名字前缀
executor.setThreadNamePrefix("customize-thread-");
/*
当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)
CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
三、使用springboot默认的线程池
3.1 通过@Async注解调用
@SpringBootApplication
@EnableAsync
public class ThreadpoolApplication {
public static void main(String[] args) {
SpringApplication.run(ThreadpoolApplication.class, args);
}
}
@Service
public class AsyncTest {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
// 使用默认线程池
@Async
public void hello(String name){
//这里使用logger 方便查看执行的线程是什么
logger.info("默认线程池:异步线程启动 started."+name);
}
// 使用自定义线程池
@Async("customizeThreadPool")
public void hi(String name){
//这里使用logger 方便查看执行的线程是什么
logger.info("自定义线程池:异步线程启动 started."+name);
}
}
@Autowired
AsyncTest asyncTest;
@Test
void contextLoads() throws InterruptedException {
asyncTest.hello("afsasfasf");
//一定要休眠 不然主线程关闭了,子线程还没有启动
Thread.sleep(1000);
}
3.2 直接调用ThreadPoolTaskExecutor
直接注入ThreadPoolTaskExecutor
@SpringBootTest
class ThreadPoolApplicationTests {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
AsyncTest asyncTest;
@Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Test
void asyncTest0() throws InterruptedException {
asyncTest.hello("async注解创建");
threadPoolTaskExecutor.submit(new Thread(()->{
logger.info("threadPoolTaskExecutor 创建线程");
}));
//一定要休眠 不然主线程关闭了,子线程还没有启动
Thread.sleep(1000);
}
}
以上,请参考,谢谢!