1.springboot线程池配置
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
/**
* 默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
* 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
* 当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
*/
/** 核心线程数(默认线程数) */
private static final int corePoolSize = 1;
/** 最大线程数 */
private static final int maxPoolSize = 5;
/** 允许线程空闲时间(单位:默认为秒) */
private static final int keepAliveTime = 10;
/** 缓冲队列大小 */
private static final int queueCapacity = 0;
/** 线程池名前缀 */
private static final String threadNamePrefix = "Async-Service-";
@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名
public ThreadPoolTaskExecutor taskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//maxPoolSize+queueCapacity多余的线程丢弃抛出异常
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
//maxPoolSize+queueCapacity多余的线程丢弃
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
//maxPoolSize+queueCapacity多余的线程丢弃
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
// 初始化
executor.initialize();
return executor;
}
@Bean("taskExecutorCOMM") // bean的名称,默认为首字母小写的方法名
public ThreadPoolTaskExecutor taskExecutorCOMM(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
// 初始化
executor.initialize();
return executor;
}
@Bean("taskExecutorICBC") // bean的名称,默认为首字母小写的方法名
public ThreadPoolTaskExecutor taskExecutorICBC(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
// 初始化
executor.initialize();
return executor;
}
}
2.创建异步调用方法
@Service
public class OrderTaskServic {
@Autowired
private BOCOrderService bOCOrderService;
@Autowired
private COMMOrderService cOMMOrderService;
@Autowired
private ICBCOrderService iCBCOrderService;
// 订单处理任务
public void orderTask() throws InterruptedException {
for (int i = 0; i < 4; i++) {
bOCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
bOCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
bOCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
cOMMOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
cOMMOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
cOMMOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
iCBCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
iCBCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
iCBCOrderService.roll("513436200012213845", "展示", "云南", "泸水", "15236528965");
}
}
}
3.创建三个异步方法
@Slf4j
@Service
public class COMMOrderService {
@Async("taskExecutorCOMM")
public void roll(String cardId, String name, String provinceAbbr, String cityAbbr, String phone) {
log.info("[{}]COMM开始轮询", Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("[{}]COMM结束轮询", Thread.currentThread().getId());
}
}
@Slf4j
@Service
public class ICBCOrderService {
@Async("taskExecutorICBC")
public void roll(String cardId, String name, String provinceAbbr, String cityAbbr, String phone) {
log.info("[{}]ICBC开始轮询",Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("[{}]ICBC结束轮询",Thread.currentThread().getId());
}
}
@Slf4j
@Service
public class BOCOrderService {
@Async("taskExecutor")
public void roll(String cardId, String name, String provinceAbbr, String cityAbbr, String phone) {
log.info("[{}]开始轮询",Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("[{}]结束轮询",Thread.currentThread().getId());
}
}
4.输出结果
5.注意事项:
如下方式会使@Async失效
一、异步方法使用static修饰
二、异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
三、调用方法不能与被调用的异步方法在同一个类中
四、类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
五、如果使用SpringBoot框架必须在启动类中加@EnableAsync注解