@Async用于异步调用,用线程池里的一个线程去处理,主线程无须等待,直接执行以后的语句官方文档java
例如:支付(步骤A)->开锁(步骤B)->支付信息入库(步骤C)->...,例如开锁步骤和主程序其余步骤关联不强(支付完成即使是不开锁,用户仍然能够经过界面启动)且耗时(物联网设备通讯问题,等待返回须要时间以及失败重试等),就能够考虑用异步调用去处理spring
package com.virgo.user.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author zhaozha
* @date 2019/10/18 下午2:09
*/
@Configuration
public class TaskConfiguration {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(2);
// 最大线程数
// 空闲线程数=最大线程数-核心线程数
executor.setMaxPoolSize(4);
// 队列最大容量
executor.setQueueCapacity(2);
// 空闲线程数最大存活时间
executor.setKeepAliveSeconds(60);
// 线程池名的前缀
executor.setThreadNamePrefix("taskExecutor-");
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
复制代码
@EnableAsync
复制代码
// 本次测试在Service层加注解
@Override
public void pay() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("支付完成");
}
@Override
@Async("taskExecutor")
public Future<String> unlock() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("开锁完成");
return new AsyncResult<>("开锁完成");
}
@Override
public void record() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("记录完成");
}
}
// Controller层调用
...
try {
commonServiceImpl.pay();
commonServiceImpl.unlock();
commonServiceImpl.record();
} catch (Exception e) {
e.printStackTrace();
}
...
复制代码
拒绝策略(todo)bash
优雅停机dom
// 声明线程池的时候配置
//1.线程池关闭的时候先等待任务的完成在销毁bean
setWaitForTasksToCompleteOnShutdown(true)
//2.线程池关闭的时候先等待任务的最大时间,超过就强制销毁
setAwaitTerminationSeconds(60)
复制代码