# 线程池在springboot中的创建及使用
## 第一步 配置线程池
### 创建线程池的Bean
```
@Configuration
@EnableAsync
@Slf4j
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() {
Home("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;
}
}
```
### 编写配置文件,设置线程数、队列大小等
```
# 异步线程配置
async:
executor:
thread:
# 配置核心线程数
core_pool_size: 5
# 配置最大线程数
max_pool_size: 5
# 配置队列大小
queue_capacity: 99999
name:
# 配置线程池中的线程的名称前缀
prefix: async-service-
```
## 第二步 线程池的使用
### 定义一个函数式接口
```
@FunctionalInterface
public interface ExecutorFunctional {
void execute() throws Exception;
}
```
### 定义一个异步调用的接口
```
public interface AsyncService {
void executeAsync(ExecutorFunctional target);
}
```
### 实现异步调用接口
```
@Service
public class AsyncServiceImpl implements AsyncService {
@Override
@Async("asyncServiceExecutor")
public void executeAsync(ExecutorFunctional target) {
try {
target.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
### 异步的调用
```
@GetMapping("func")
public void testFunctionalExecutor() {
// CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
asyncService.executeAsync(() -> {
int random = (int) (2 + Math.random() * 8);
Home("线程睡{}秒", random);
Thread.sleep(random * 1000);
// latch.countDown();
Home("子线程睡{}秒,执行完毕", random);
});
}
// latch.await();
Home("主线程执行完毕");
}
```
## 第三步 如果想查看线程池信息,继承ThreadPoolTaskExecutor,重写里面的方法
### 继承ThreadPoolTaskExecutor
```
@Slf4j
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
private void showThreadPoolInfo(String prefix) {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (null == threadPoolExecutor) {
return;
}
Home("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
prefix,
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
@Override
public void execute(Runnable task) {
showThreadPoolInfo("1. do execute");
super.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
showThreadPoolInfo("2. do execute");
super.execute(task, startTimeout);
}
@Override
public Future> submit(Runnable task) {
showThreadPoolInfo("1. do submit");
return super.submit(task);
}
@Override
public Future submit(Callable task) {
showThreadPoolInfo("2. do submit");
return super.submit(task);
}
@Override
public ListenableFuture> submitListenable(Runnable task) {
showThreadPoolInfo("1. do submitListenable");
return super.submitListenable(task);
}
@Override
public ListenableFuture submitListenable(Callable task) {
showThreadPoolInfo("2. do submitListenable");
return super.submitListenable(task);
}
}
```
### 线程池配置,new VisiableThreadPoolTaskExecutor
```
@Configuration
@EnableAsync
@Slf4j
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() {
Home("start asyncServiceExecutor");
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
//配置核心线程数
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;
}
}
```