SpringBoot使用@Async注解,实现异步任务
1.直接在方法上加@Async注解,标明为异步任务:
@Component
public class MyAsyncTask {
@Async
public void asyncImportTask(String jsonList){
//...具体业务逻辑
//从redis缓存中查询数据(使用若依框架自带的redis方法)
Data redisData = RedisUtils.getCacheObject(DataEnum.NUMONE.getValue());
if(ObjectUtil.isEmpty(redisData)){
//将数据查询后存入redis缓存1H
RedisUtils.setCacheObject(DataEnum.NUMONE.getValue(), Data, Duration.ofHours(1));
}
}
}
2.设置默认的Async的线程,且开启异步配置,即配置上@EnableAsync注解:
@EnableAsync(proxyTargetClass = true)
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {
@Autowired
@Qualifier("scheduledExecutorService")
private ScheduledExecutorService scheduledExecutorService;
/**
* 自定义 @Async 注解使用系统线程池
*/
@Override
public Executor getAsyncExecutor() {
return scheduledExecutorService;
}
/**
* 异步执行异常处理
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
throwable.printStackTrace();
StringBuilder sb = new StringBuilder();
sb.append("Exception message - ").append(throwable.getMessage())
.append(", Method name - ").append(method.getName());
if (ArrayUtil.isNotEmpty(objects)) {
sb.append(", Parameter value - ").append(Arrays.toString(objects));
}
throw new ServiceException(sb.toString());
};
}
}
3.使用的线程池相关配置:
//线程池配置
@Configuration
public class ThreadPoolConfig {
/**
* 核心线程数 = cpu 核心数 + 1
*/
private final int core = Runtime.getRuntime().availableProcessors() + 1;
@Autowired
private ThreadPoolProperties threadPoolProperties;
@Bean(name = "threadPoolTaskExecutor")
@ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(core);
executor.setMaxPoolSize(core * 2);
executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
/**
* 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(core,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
}
};
}
}
4.线程池配置属性
//线程池配置属性
@Data
@Component
@ConfigurationProperties(prefix = "thread-pool")
public class ThreadPoolProperties {
/**
* 是否开启线程池
*/
private boolean enabled;
/**
* 队列最大长度
*/
private int queueCapacity;
/**
* 线程池维护线程所允许的空闲时间
*/
private int keepAliveSeconds;
}
5.系统全局线程池配置
# 全局线程池相关配置
thread-pool:
# 是否开启线程池
enabled: true
# 队列最大长度
queueCapacity: 256
# 线程池维护线程所允许的空闲时间
keepAliveSeconds: 300
注意:调用被@Async注解的方法时,调用方法不能与被调用方法放在同一类中,否则注解不生效