基于CompletableFuture的异步任务获取数据并拿到返回值

一个基于CompletableFuture的异步任务获取数据并拿到返回值的小demo,希望有更好的办法,目前留作自用。

使用线程去异步获取不同渠道的数据,并且拿到每个线程的返回值。
待解决问题:某一个线程过长时间没有拿到返回值问题。
 // 定义渠道
 private static final String[] tenantName = {"美团", "饿了吗", "京东到家", "阿斯尔顿"};

 // 线程池
 private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5, 8, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());


假装去其他渠道获取数据

	// 模拟 根据渠道查询数据
    private static String feginQueryByTenantId(String tenantId) throws InterruptedException {
        Thread.sleep(2000); // 假装查询两秒
        return tenantId + "查询完毕";
    }

方法一

    // 根据渠道集合查询数据 方法一
    private static List<String> function_1(){

        CopyOnWriteArrayList<FutureTask<String>> futureTaskArrayList = new CopyOnWriteArrayList<>();

        // 遍历渠道id或者渠道唯一标识
        Arrays.stream(tenantName).forEach(name -> {

            FutureTask<String> futureTask = new FutureTask<>(() -> {
                // 此处写根据渠道查询业务的方法, 比如内部返回值之类的
                Thread.sleep(2000);
                return name + "OK";
            });
            executor.submit(futureTask);
            futureTaskArrayList.add(futureTask);
        });

        // "美团", "饿了吗", "京东到家", "阿斯尔顿" 所有品牌返回的数据集合
        return futureTaskArrayList.stream().map(task -> {
            try {
                // 获取futureTask里边的返回值
                // 注意,get方法是阻塞的,如果该线程返回值没有返回,则会等待到返回后,再继续get下一个线程
                return task.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            return null;
        }).collect(Collectors.toList());
    }

方法二

 // 方式二, 利用CompletableFuture查询多渠道
    private static List<String> function_2(){
        // 存放各个渠道将要查询的任务
        CopyOnWriteArrayList<CompletableFuture<String>> futureTaskArrayList = new CopyOnWriteArrayList<>();

        Arrays.stream(tenantName).forEach(tenant -> {
            // supplyAsync 异步查询
            CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    // 调用feign接口查询不同渠道
                    return feginQueryByTenantId(tenant);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            });
            futureTaskArrayList.add(stringCompletableFuture);
        });

        // 将任务List转换成数组
        CompletableFuture[] completableFutures = futureTaskArrayList.toArray(new CompletableFuture[futureTaskArrayList.size()]);
        // 把任务数组放入 CompletableFuture 内.  // allOf代表必须等所有任务都返回后才继续, anyOf代表只要有一个任务返回数据,就直接下一步,不等别的了
        CompletableFuture<Void> allCompletableFuture = CompletableFuture.allOf(completableFutures);
        // 返回所有渠道的数据,并拼装一块
        List<String> join = allCompletableFuture.thenApply(e -> futureTaskArrayList.stream().map(CompletableFuture::join).collect(Collectors.toList())).join();
        return join;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值