1. 配置
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;
@Configuration("JackThreadPoolExecutorCore")
public class JackThreadPoolExecutor {
@Bean("jackExecutorCore")
public Executor jackExecutorCore(){
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 配置核心线程数
taskExecutor.setCorePoolSize(8);
// 配置最大线程数
taskExecutor.setMaxPoolSize(16);
// 配置队列大小
taskExecutor.setQueueCapacity(10000);
// 设置线程活跃时间(秒)
taskExecutor.setKeepAliveSeconds(60);
// 配置线程池中的线程的名称前缀
taskExecutor.setThreadNamePrefix("JackExecutorCore---");
//当调度器shutdown被调用时等待当前被调度的任务完成
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
// 达到队列最大,减缓新任务的提交速度,并由调用线程处理
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待的时间,不能无限的等待下去
taskExecutor.setAwaitTerminationSeconds(60);
return taskExecutor;
}
}
在启动类上添加注解
//开启异步调用
@EnableAsync
2. 报错
org.springframework.web.util.NestedServletException:
Request processing failed; nested exception is org.springframework.aop.AopInvocationException:
Null return value from advice does not match primitive return type for: public int
找到出错的代码
这时候我们发现使用了@Async
注解
但是返回值是基本类型, 但是我们查看CglibAopProxy
切面代理类里面返回值是Object
转类型失败. 需要改成包装类Integer
.
3.注意事项
原文链接https://blog.csdn.net/mawenshu316143866/article/details/86504689
一、异步方法不能使用static修饰
二、异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
三、异步方法不能与调用方法在同一个类中
四、类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
五、如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解
六、在Async 方法上标注@Transactional是没用的。 在Async 方法调用的方法上标注@Transactional 有效。