Spring 异步处理使用方案
一. 实现 AsyncConfigurer
@Slf4j
@Configuration
@EnableAsync
public class MyAsyncConfigurer implements AsyncConfigurer {
/**
* The {@link Executor} instance to be used when processing async
* method invocations.
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return executor;
}
/**
* The {@link AsyncUncaughtExceptionHandler} instance to be used
* when an exception is thrown during an asynchronous method execution
* with {@code void} return type.
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
/**
* Handle the given uncaught exception thrown from an asynchronous method.
*
* @param ex the exception thrown from the asynchronous method
* @param method the asynchronous method
* @param params the parameters used to invoked the method
*/
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
log.error("异步处理异常 方法为:{},参数为:{},异常为:{}", method, params, ex);
}
};
}
}
使用方式
@Async
@GetMapping("demo01")
public void demo01(){
log.info("demo01处理.......");
}
log输出
2022-11-29 INFO 29280 --- [ MyExecutor-1] com.javayh.async.web.AsyncController : demo01处理.......
自定义线程池,替换默认的bean
@Slf4j
@Configuration
@EnableAsync
public class ExecutorConfig {
private static String namePrefix = "async-javayh";
@Bean(name = "asyncExecutor01")
public Executor asyncExamExecutor() {
log.info("start asyncExamExecutor");
//计算计算机的核数
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
int processors = Runtime.getRuntime().availableProcessors();
//配置核心线程数
executor.setCorePoolSize(processors * 5);
//配置最大线程数
executor.setMaxPoolSize(processors * 5);
//配置队列大小
executor.setQueueCapacity(1000);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
使用方式
@Async("asyncExecutor01")
@GetMapping("demo02")
public void demo02(){
log.info("demo02处理.......");
}
log输出
2022-11-29 INFO 29280 --- [ async-javayh1] com.javayh.async.web.AsyncController : demo02处理.......
重写ThreadPoolTaskExecutor
@Slf4j
public class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
public MyThreadPoolTaskExecutor() {
super();
}
private void showThreadPoolInfo(String prefix) {
ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
if (null == threadPoolExecutor) {
return;
}
log.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",
this.getThreadNamePrefix(),
prefix,
threadPoolExecutor.getTaskCount(),
threadPoolExecutor.getCompletedTaskCount(),
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size());
}
@Override
public void execute(Runnable task) {
showThreadPoolInfo("Runnable do execute");
super.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
showThreadPoolInfo("Runnable startTimeout do execute");
super.execute(task, startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
showThreadPoolInfo("Runnable do submit");
return super.submit(task);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
showThreadPoolInfo("Callable do submit");
return super.submit(task);
}
@Override
public ListenableFuture<?> submitListenable(Runnable task) {
showThreadPoolInfo("Runnable do submitListenable");
return super.submitListenable(task);
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
showThreadPoolInfo("Callable do submitListenable");
return super.submitListenable(task);
}
}
配置重写后的线程池
@Slf4j
@Configuration
@EnableAsync
public class MyExecutorConfig {
private static String namePrefix = "my-async-javayh";
@Bean(name = "asyncExecutor02")
public Executor asyncExamExecutor() {
log.info("start asyncExamExecutor");
//计算计算机的核数
ThreadPoolTaskExecutor executor = new MyThreadPoolTaskExecutor();
int processors = Runtime.getRuntime().availableProcessors();
//配置核心线程数
executor.setCorePoolSize(processors * 5);
//配置最大线程数
executor.setMaxPoolSize(processors * 5);
//配置队列大小
executor.setQueueCapacity(1000);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
使用方式
@Async("asyncExecutor02")
@GetMapping("demo03")
public void demo03(){
log.info("demo32处理.......");
}
log输出
2022-11-29 INFO 29280 --- [nio-8080-exec-4] c.j.a.config.MyThreadPoolTaskExecutor : my-async-javayh, Callable do submit,taskCount [0], completedTaskCount [0], activeCount [0], queueSize [0]
2022-11-29 INFO 29280 --- [y-async-javayh1] com.javayh.async.web.AsyncController : demo32处理.......
2022-11-29 INFO 29280 --- [nio-8080-exec-5] c.j.a.config.MyThreadPoolTaskExecutor : my-async-javayh, Callable do submit,taskCount [1], completedTaskCount [1], activeCount [0], queueSize [0]
2022-11-29 INFO 29280 --- [y-async-javayh2] com.javayh.async.web.AsyncController : demo32处理.......
2022-11-29 INFO 29280 --- [nio-8080-exec-6] c.j.a.config.MyThreadPoolTaskExecutor : my-async-javayh, Callable do submit,taskCount [2], completedTaskCount [2], activeCount [0], queueSize [0]
2022-11-29 INFO 29280 --- [y-async-javayh3] com.javayh.async.web.AsyncController : demo32处理.......
今天的分享就到这里,源码地址https://github.com/yanghaiji/IT-Demo/tree/main/async-config-demo
也可以添加小编微信 372787553,进入社群交流群