controller方法中存在。
1.查询数据库获取结果AList
2.查询数据库获取结果BList
3.AList与BList结果进行处理
此时可以使用线程池异步处理1和2.
配置文件:
excutor: # 线程池配置
corePoolSize: 4 # 核心线程数
maxPoolSize: 20 # 最大线程数
queueCapacity: 20 # 最大等待队列
keepAliveSeconds: 20 # 最大存活时长
allowCoreThreadTimeOut: true # 允许核心线程超时后关闭
线程池配置属性类
@Data
@Configuration
@ConfigurationProperties(prefix = "excutor")
public class ExcutorProperties {
private int corePoolSize;
private int maxPoolSize;
private int queueCapacity;
private int keepAliveSeconds;
private Boolean allowCoreThreadTimeOut;
}
线程池配置类
@Configuration
@EnableAsync
public class AsyncConfig {
@Autowired
private ExcutorProperties excutorProperties;
@Primary
@Bean
@Qualifier("taskExecutor")
public Executor taskExecutor() {
// Spring 默认配置是核心线程数大小为1,最大线程容量大小不受限制,队列容量也不受限制。
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(excutorProperties.getCorePoolSize()); // 核心线程数
executor.setMaxPoolSize(excutorProperties.getMaxPoolSize()); // 最大线程数
executor.setQueueCapacity(excutorProperties.getQueueCapacity()); // 队列大小
executor.setKeepAliveSeconds(excutorProperties.getKeepAliveSeconds()); // 保活时长
executor.setAllowCoreThreadTimeOut(excutorProperties.getAllowCoreThreadTimeOut());
// 当最大池已满时,此策略保证不会丢失任务请求,但是可能会影响应用程序整体性能。
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("taskExecutor-");
executor.initialize();
return executor;
}
}
service调用类
@Slf4j
@Service
public class TestService {
/**
* 异步调用方法,返回future
*
* @return
*/
@Async("taskExecutor")
public Future<Integer> getNumber() {
log.info("===getNumber start===");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("===getNumber end===");
return new AsyncResult<>(new Integer(1));
}
/**
* 异步调用方法,返回future
*
* @return
*/
@Async("taskExecutor")
public Future<String> getString() {
log.info("===getString start===");
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("===getString end===");
return new AsyncResult<>(String.valueOf(new Random().nextInt()));
}
}
controller方法
@GetMapping(value = "/get3")
@HandlingTime
public void get3() throws ExecutionException, InterruptedException {
log.info("===========================");
Future<Integer> number = testService.getNumber();
log.info("num================");
Future<String> string = testService.getString();
log.info("string================");
log.info("------------" + number.get()); // 阻塞等待获取结果
log.info("------------" + string.get()); // 阻塞等待获取结果
}
==========================================================================================
2021-01-08补充:
static Random r = new Random(100);
public static String getStr() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return r.nextInt() + "";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorSer0vice executorService = Executors.newFixedThreadPool(5);
List<Future<String>> list = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
Future<String> future = executorService.submit(WechatCustomerCtrl::getStr);
list.add(future);
System.out.println(future.get());
}
for (Future<String> future : list) {
System.out.println(future.get());
}
// 5个线程执行时长 2231ms
// 单个线程执行时长10959ms
System.out.println("========" + (System.currentTimeMillis() - start) + "ms");
executorService.shutdown();
}