Java_CompletableFuture异步

Java_CompletableFuture异步

1.创建CompletableFuture

有多种方式可以创建CompletableFuture:

// 从一个供给函数创建
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello");
 
// 从一个运行函数创建 
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("Hello"));
 
// 从一个已有的结果创建
CompletableFuture<String> future = CompletableFuture.completedFuture("Hello");
2.链式调用

CompletableFuture支持链式调用,可以方便地对异步结果进行转换和组合:

CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(s -> s + " World") // 对结果进行转换
    .thenCompose(s -> getResult(s)); // 组合另一个异步操作
3.异常处理

通过exceptionally()方法可以对异常情况进行处理:

String result = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("error"); 
}).exceptionally(ex -> {
    // 处理异常
    return "Default Value";
}).get();
4.组合多个CompletableFuture

通过allOf,anyOf这两种方式我们可以让任务之间协同工作,join()和get()方法都是阻塞调用它们的线程(通常为主线程)来获取CompletableFuture异步之后的返回值。

get() 方法会抛出经检查的异常,可被捕获,自定义处理或者直接抛出。

而 join() 会抛出未经检查的异常。
// 等待所有任务完成
CompletableFuture.allOf(future1, future2, future3).get();
CompletableFuture.allOf(future1, future2, future3).join();
 
// 只要任意一个任务完成即可  
CompletableFuture.anyOf(future1, future2, future3).get();
CompletableFuture.anyOf(future1, future2, future3).join();
 
// 规定超时时间,防止一直堵塞
CompletableFuture.allOf(future1, future2, future3).get(6, TimeUnit.SECONDS);
5.设置超时时间

我们可以通过下面的方式可以设置某个CompletableFuture的超时时间:

String result = CompletableFuture.supplyAsync(() -> "Hello")
                 .completeOnTimeout("Timeout!", 1, TimeUnit.SECONDS)
                 .get();

代码实现

1.初始化线程池

application.yaml配置文件:

# 线程池配置
thread:
  pool:
    corePoolSize: 10
    maxPoolSize: 20
    queueCapacity: 100
    keepAliveSeconds: 60

线程池配置类ThreadPoolConfig

@Configuration
public class ThreadPoolConfig {
 
    @Value("${thread.pool.corePoolSize}")
    private int corePoolSize;
 
    @Value("${thread.pool.maxPoolSize}")
    private int maxPoolSize;
 
    @Value("${thread.pool.queueCapacity}")
    private int queueCapacity;
 
    @Value("${thread.pool.keepAliveSeconds}")
    private int keepAliveSeconds;
 
    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        return new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveSeconds,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(queueCapacity),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }
}
2.封装响应信息聚合对象
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserBehaviorDataDTO {
 
    //用户ID
    private Long userId ;
 
    //发布文章数
    private Long articleCount ;
 
    //点赞数
    private Long likeCount ;
 
    //粉丝数
    private Long fansCount ;
 
    //消息数
    private Long msgCount ;
 
    //收藏数
    private Long collectCount ;
 
    //关注数
    private Long followCount ;
 
    //红包数
    private Long redBagCount ;
 
    // 卡券数
    private Long couponCount ;
 
}
3.通过CompletableFuture异步执行每一个查询操作

如下,我们定义了一个异步任务类,创建每一个查询操作的CompletableFuture异步任务放入线程中执行,并利用allOf等待全部任务执行完成,执行完成后组装查询信息到聚合对象中返回

@Slf4j
@Component
public class MyFutureTask {
    @Resource
    UserService userService;
 
    // 线程池
    @Resource
    private ExecutorService executor;
    public UserBehaviorDataDTO getUserAggregatedResult(final Long userId) {
        System.out.println("MyFutureTask的线程:" + Thread.currentThread());
        try {
            // 1.发布文章数
            CompletableFuture<Long> articleCountFT = CompletableFuture.supplyAsync(() -> userService.countArticleCountByUserId(userId), executor);
            // 2.点赞数
            CompletableFuture<Long> LikeCountFT = CompletableFuture.supplyAsync(() -> userService.countLikeCountByUserId(userId), executor);
            // 3.粉丝数
            CompletableFuture<Long> fansCountFT = CompletableFuture.supplyAsync(() -> userService.countFansCountByUserId(userId), executor);
            // 4.消息数
            CompletableFuture<Long> msgCountFT = CompletableFuture.supplyAsync(() -> userService.countMsgCountByUserId(userId), executor);
            // 5.收藏数
            CompletableFuture<Long> collectCountFT = CompletableFuture.supplyAsync(() -> userService.countCollectCountByUserId(userId), executor);
            // 6.关注数
            CompletableFuture<Long> followCountFT = CompletableFuture.supplyAsync(() -> userService.countFollowCountByUserId(userId), executor);
            // 7.红包数
            CompletableFuture<Long> redBagCountFT = CompletableFuture.supplyAsync(() -> userService.countRedBagCountByUserId(userId), executor);
            // 8.卡券数
            CompletableFuture<Long> couponCountFT = CompletableFuture.supplyAsync(() -> userService.countCouponCountByUserId(userId), executor);
 
            // 等待全部线程执行完毕 这里一定要设超时时间,不然会一直等待
            CompletableFuture.allOf(articleCountFT, LikeCountFT, fansCountFT, msgCountFT, collectCountFT, followCountFT, redBagCountFT, couponCountFT).get(6, TimeUnit.SECONDS);
 
            // 必须设置合理的超时时间
            UserBehaviorDataDTO userBehaviorData = UserBehaviorDataDTO.builder().articleCount(articleCountFT.get()).likeCount(LikeCountFT.get()).fansCount(fansCountFT.get()).msgCount(msgCountFT.get()).collectCount(collectCountFT.get()).followCount(followCountFT.get()).redBagCount(redBagCountFT.get()).couponCount(couponCountFT.get()).build();
            return userBehaviorData;
        } catch (Exception e) {
            log.error("get user behavior data error", e);
            return new UserBehaviorDataDTO();
        }
    }
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值