线程池的优点
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗
- 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行
- 可以对线程做统一管理。
1.配置线程池
修改配置文件
# 异步线程配置
# 配置核心线程数
async:
executor:
thread:
core_pool_size: 5 # 配置核心线程数
max_pool_size: 5 # 配置最大线程数
queue_capacity: 99999 # 配置队列大小
name:
prefix: async-service- # 配置线程池中的线程的名称前
线程池配置类
package com.bt.springboot.config;
import com.bt.springboot.task.ThreadPoolMonitor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author zkx
* @Date 2022/12/6 21:42
*/
@Slf4j
@Configuration
@EnableAsync
public class ExecutorConfig {
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Bean(name = "asyncServiceExecutor")
public Executor asyncServiceExecutor() {
log.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.监控类
package com.bt.springboot.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: ChenBin
*/
@Slf4j
@Component
public class ThreadPoolMonitor extends ThreadPoolTaskExecutor {
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Scheduled(cron = "0/1 * * * * ? ")
private void showThreadPoolInfo() {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (namePrefix.equals(this.getThreadNamePrefix())){
log.info("{} taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
}
}
开启定时任务
3.修改线程池配置类
将ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
修改为ThreadPoolTaskExecutor executor = new ThreadPoolMonitor();
4.测试相关类
AsyncService
package com.bt.springboot.async;
/**
* @author zkx
* @Date 2022/12/6 21:47
*/
public interface AsyncService {
/**
* 执行异步任务
* 可以根据需求,自己加参数拟定,我这里就做个测试演示
*/
void executeAsync();
}
AsyncServiceImpl
package com.bt.springboot.async.impl;
import com.bt.springboot.async.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/**
* @author zkx
* @Date 2022/12/6 21:48
*/
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
@Override
@Async("asyncServiceExecutor")
public void executeAsync() {
int i = 5;
while(i > 0){
i--;
log.info("execute task");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
}
AsyncController
package com.bt.springboot.web.controller;
import com.bt.springboot.async.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zkx
* @Date 2022/12/9 17:38
*/
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@GetMapping("/asyncTask")
public void asyncTask(){
asyncService.executeAsync();
}
}
5.启动
1.执行任务前
2.执行任务
3.任务完成