一、准备工作
1、@Async注解的使用
转:https://blog.csdn.net/hry2015/article/details/67640534
2、CompletableFuture的使用
转:https://www.jianshu.com/p/6bac52527ca4
https://www.cnblogs.com/dennyzhangdd/p/7010972.html
二、使用@Async和CompletableFuture 实现过程示例
1、自定义配置线程池
(1)配置 @EnableAsync 注解,启用异步任务
/**
* 文件描述
* 线程池配置
* @author hjj
* @date 2020年07月22日 16:19
*/
@Configuration
@ComponentScan("com.renai.lovepd.web.system.service")
@EnableAsync
@Slf4j
public class TaskPoolConfig implements AsyncConfigurer {
//参数初始化
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心线程数量大小
private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//线程池最大容纳线程数
private static final int maxPoolSize = CPU_COUNT * 2 + 1;
//阻塞队列
private static final int workQueue = 20;
//线程空闲后的存活时长
private static final int keepAliveTime = 30;
@Override
@Bean("asyncTaskExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//核心线程数
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
//最大线程数
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
//等待队列
threadPoolTaskExecutor.setQueueCapacity(workQueue);
//线程前缀
threadPoolTaskExecutor.setThreadNamePrefix("taskExecutor-");
//线程池维护线程所允许的空闲时间,单位为秒
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveTime);
// 线程池对拒绝任务(无线程可用)的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
}
}
2、编写异步任务的实现方法
(1)在方法上添加 @Async 注解
(2)返回值声明为: CompletableFuture
(3)配置 @Component 或 @ Service 等,保证可以组件扫描到
注:异步任务的实现方法要定义在一个类中,不能与调用它的方法写在同一个类中,不然不起效果
/**
* 文件描述
* 任务异步处理
* @author hjj
* @date 2020年07月22日 16:33
*/
@Component
@Slf4j
public class AsyncTask {
@Async("asyncTaskExecutor")
public CompletableFuture<String> getUserInfoByCompletableFuture(String userName) {
String userInfo="";
try{
Thread.sleep(10);
userInfo = userName+"的基本信息!";
} catch (InterruptedException e) {
log.error(e.getMessage(),e);
e.printStackTrace();
}
return CompletableFuture.completedFuture(userInfo);
}
}
3、调用异步任务
/**
* 文件描述
*
* @author hjj
* @date 2020年07月22日 16:48
*/
@Component
@Slf4j
public class CompletableFutureDemo {
@Autowired
private AsyncTask asyncTask;
List<String> batchGetUserInfoByCompletableFuture(List<String> userNameList) throws InterruptedException, ExecutionException{
List<CompletableFuture<String>> userInfoFutrues = userNameList.stream().map(userName->asyncTask.getUserInfoByCompletableFuture(userName)).collect(Collectors.toList());
return userInfoFutrues.stream().map(CompletableFuture::join).collect(Collectors.toList());
}
}
4、测试
@Test
public void CompletableFutureTest()throws InterruptedException, ExecutionException {
List<String> userNameList = new ArrayList<>();
for(int i=0;i<300;i++){
userNameList.add("Ada"+i);
}
long start =System.currentTimeMillis();
List<String> userInfoResult = completableFutureDemo.batchGetUserInfoByCompletableFuture1(userNameList);
long end =System.currentTimeMillis();
log.info("CompletableFuture耗时--》"+ (end-start)+"ms");
}
测试结果显示:CompletableFuture耗时--》372ms
参考:
https://blog.csdn.net/u014203449/article/details/88830287?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-1-88830287.nonecase
网友评论