【问题标题】:how to assign the return type of completableFuture.supplyAsync() to the object?如何将 completableFuture.supplyAsync() 的返回类型分配给对象?
【发布时间】:2019-04-04 11:58:22
【问题描述】:

我在 foreach 循环中定义了 completableFuture.supplyAsync(),所以每个条目(每个异步任务)添加一个列表,我需要从 completableFuture.supplyAsync() 获取最终列表(在所有异步任务添加列表之后)。如何实现这个?

代码sn-p:

    unporcessedList.forEach(entry -> {                       
    CompletableFuture<List<ChangeLog>> cf =  
    CompletableFuture.supplyAsync((Supplier<List<ChangeLog>>) () -> {                            
    mongoDBHelper.processInMongo(entry, getObject(entry, map),entryList);
    return entryList;
    }, executor); 
    });

【问题讨论】:

    标签: java concurrency java-8 completable-future


    【解决方案1】:

    非阻塞版本

    一般示例:

        List<String> entries = new ArrayList<>(2);
        entries.add("first");
        entries.add("second");
    
        List<CompletableFuture<String>> completableFutures = entries.stream()
                .map((entry) -> {
                            return CompletableFuture.supplyAsync(() -> {
                                try {
                                    Thread.sleep(new Random().nextInt(5000) + 500);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                return entry.concat(String.valueOf(entry.length()));
                            }).thenApply((e) -> new StringBuilder(e).reverse().toString());
                        }
                ).collect(Collectors.toList());
    
        CompletableFuture
                .allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]))
                .thenApply((v) -> completableFutures.stream().map((cf) -> cf.join()))
                .get()
                .forEach(System.out::println);
    

    你的情况:

        List<CompletableFuture<List<ChangeLog>>> completableFutures = unporcessedList.stream()
                .map((entry) -> {
                            return CompletableFuture.supplyAsync((Supplier<List<ChangeLog>>) () -> {
                                mongoDBHelper.processInMongo(entry, getObject(entry, map), entryList);
                                return entryList;
                            }, executor);
                        }
                ).collect(Collectors.toList());
    
        CompletableFuture
                .allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]))
                .thenApply((v) -> completableFutures.stream().map((cf) -> cf.join()))
                .get()
                .forEach(System.out::println);
    

    【讨论】:

      【解决方案2】:

      您可以使用 get() 方法来阻止您的应用程序,直到将来完成。所以使用这样的东西:

      // Block and get the result of the Future
      Supplier<List<ChangeLog>> result = cf.get();
      

      此处描述了更多示例:https://www.callicoder.com/java-8-completablefuture-tutorial/

      希望这会有所帮助。

      【讨论】:

      • 谢谢@runningriot,cf.get() 返回最终值,但我无法将其分配给供应商类型的结果,即使我尝试将 cf.get() 转换为供应商类型但得到运行时转换异常.所以我简单地写了 cf.get() 并且能够在这个方法返回类型中返回列表。
      猜你喜欢
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2013-04-11
      • 2020-05-22
      • 2020-06-12
      • 2021-05-29
      • 2020-11-15
      • 1970-01-01
      相关资源
      最近更新 更多