Spring @Async注解的使用
Spring @Async注解的使用
Spring的@Async注解的作用是让被标记的方案异步执行
前提条件:
- 启动类或配置类上加入
@EnableAsync
注解; - 需要在异步执行的方案必须是被Spring管理的JavaBean中;
- 需要异步执行的方法上必须加入
@Async
注解;
适用场景:
- 日志;
- 异步执行代码段;
需要注意的点:
- 因为Async是基于AOP实现的,调用本类中加入Async的其他方法, 不生效;
QuickStarter
在启动类加入@EnableAsync
注解后,创建两个方法用于验证
@Service
public class TestService {
@Async@SneakyThrows
public void testSync() {
TimeUnit.SECONDS.sleep(5);
System.out.println("testSync");
}
@SneakyThrows
public void testCommon() {
TimeUnit.SECONDS.sleep(5);
System.out.println("testCommon");
}
}
Controller
@GetMapping("/sync")
public String sync(){
testService.testSync();
return "sync";
}
@GetMapping("/common")
public String common(){
testService.testCommon();
return "common";
}
分别调用两个接口,发现/common
会阻塞五秒后返回结果;/sync
则会立即返回。
线程池问题
默认使用Spring创建ThreadPoolTaskExecutor。
默认核心线程数:8,
最大线程数:Integet.MAX_VALUE,
队列使用LinkedBlockingQueue,
容量是:Integet.MAX_VALUE,
空闲线程保留时间:60s,
线程池拒绝策略:AbortPolicy。
问题:并发情况下,会无无限建线程
解决线程池问题
自定义配置参数
spring:
task:
execution:
pool:
max-size: 6
core-size: 3
keep-alive: 3s
queue-capacity: 1000
thread-name-prefix: name
编写自定义线程配置类
@Configuration
@Data
public class ExecutorConfig{
/**
* 核心线程
*/
private int corePoolSize;
/**
* 最大线程
*/
private int maxPoolSize;
/**
* 队列容量
*/
private int queueCapacity;
/**
* 保持时间
*/
private int keepAliveSeconds;
/**
* 名称前缀
*/
private String preFix;
@Bean
public Executor myExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix(preFix);
executor.setRejectedExecutionHandler( new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
}
参考: