Java 8 Java 8可完全未来所有不同的数据类型

Java 8 Java 8可完全未来所有不同的数据类型,java-8,completable-future,Java 8,Completable Future,我有3个完整的期货,所有3个都返回不同的数据类型 我希望创建一个result对象,它是所有3个函数返回的结果的组合 因此,我当前的工作代码如下所示: public ClassD getResultClassD() { ClassD resultClass = new ClassD(); CompletableFuture<ClassA> classAFuture = CompletableFuture.supplyAsync(() -> service.get

我有3个完整的期货,所有3个都返回不同的数据类型

我希望创建一个result对象,它是所有3个函数返回的结果的组合

因此,我当前的工作代码如下所示:

public ClassD getResultClassD() {

    ClassD resultClass = new ClassD();
    CompletableFuture<ClassA> classAFuture = CompletableFuture.supplyAsync(() -> service.getClassA() );
    CompletableFuture<ClassB> classBFuture = CompletableFuture.supplyAsync(() -> service.getClassB() );
    CompletableFuture<ClassC> classCFuture = CompletableFuture.supplyAsync(() -> service.getClassC() );

    CompletableFuture.allOf(classAFuture, classBFuture, classCFuture)
                     .thenAcceptAsync(it -> {
                        ClassA classA = classAFuture.join();
                        if (classA != null) {
                            resultClass.setClassA(classA);
                        }

                        ClassB classB = classBFuture.join();
                        if (classB != null) {
                            resultClass.setClassB(classB);
                        }

                        ClassC classC = classCFuture.join();
                        if (classC != null) {
                            resultClass.setClassC(classC);
                        }

                     });

    return resultClass;
}
public类d getResultClassD(){
ClassD resultClass=new ClassD();
CompletableFuture classAFuture=CompletableFuture.SupplySync(()->service.getClassA());
CompletableFuture-classBFuture=CompletableFuture.supplyAsync(()->service.getClassB());
CompletableFuture类未来=CompletableFuture.SupplySync(()->service.getClassC());
CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
.然后同步(it->{
ClassA ClassA=classAFuture.join();
if(classA!=null){
结果setClassA类(classA);
}
ClassB ClassB=classBFuture.join();
if(classB!=null){
结果类setClassB(classB);
}
ClassC=classCFuture.join();
if(classC!=null){
结果setClassC类(classC);
}
});
返回结果类;
}
我的问题是:

  • 我在这里的假设是,由于我使用的是
    allOf
    theacceptsync
    ,因此此调用将是非阻塞的。我的理解正确吗

  • 这是处理返回不同结果类型的多个期货的正确方法吗

  • 在接受同步中构造
    ClassD
    对象是否正确

  • 在ThenAcceptsSync lambda中使用
    join
    getNow
    方法是否合适
    你的尝试方向正确,但不正确。您的方法
    getResultClassD()
    返回一个类型为
    ClassD
    的已实例化对象,任意线程将在该对象上调用修改方法,而
    getResultClassD()的调用方不会注意到。如果修改方法本身不是线程安全的,那么这可能会导致争用条件,而且调用方永远不会知道
    ClassD
    实例何时实际可以使用

    正确的解决办法是:

    public CompletableFuture<ClassD> getResultClassD() {
    
        CompletableFuture<ClassA> classAFuture
            = CompletableFuture.supplyAsync(() -> service.getClassA() );
        CompletableFuture<ClassB> classBFuture
            = CompletableFuture.supplyAsync(() -> service.getClassB() );
        CompletableFuture<ClassC> classCFuture
            = CompletableFuture.supplyAsync(() -> service.getClassC() );
    
        return CompletableFuture.allOf(classAFuture, classBFuture, classCFuture)
             .thenApplyAsync(dummy -> {
                ClassD resultClass = new ClassD();
    
                ClassA classA = classAFuture.join();
                if (classA != null) {
                    resultClass.setClassA(classA);
                }
    
                ClassB classB = classBFuture.join();
                if (classB != null) {
                    resultClass.setClassB(classB);
                }
    
                ClassC classC = classCFuture.join();
                if (classC != null) {
                    resultClass.setClassC(classC);
                }
    
                return resultClass;
             });
    }
    
    public CompletableFuture getResultClassD(){
    完整的未来类别未来
    =CompletableFuture.SupplySync(()->service.getClassA());
    完全未来类未来
    =CompletableFuture.SupplySync(()->service.getClassB());
    完全未来类未来
    =CompletableFuture.SupplySync(()->service.getClassC());
    返回CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
    .然后应用同步(虚拟->{
    ClassD resultClass=new ClassD();
    ClassA ClassA=classAFuture.join();
    if(classA!=null){
    结果setClassA类(classA);
    }
    ClassB ClassB=classBFuture.join();
    if(classB!=null){
    结果类setClassB(classB);
    }
    ClassC=classCFuture.join();
    if(classC!=null){
    结果setClassC类(classC);
    }
    返回结果类;
    });
    }
    
    现在,操作完成后,
    getResultClassD()
    的调用方可以使用返回的
    CompletableFuture
    查询进度状态或链相关操作,或者使用
    join()
    检索结果

    要解决其他问题,是的,此操作是异步的,在lambda表达式中使用
    join()
    join
    的创建正是因为
    Future.get()


    请注意,
    null
    测试只有在这些
    service.getClassX()
    实际返回
    null
    时才有用。如果其中一个服务调用因异常而失败,则整个操作(由
    CompletableFuture
    表示)将异常完成。

    我的方法与@Holger在其回答中所做的类似,但将服务调用包装为可选的,这将导致在ThenApplySync阶段生成更干净的代码

    CompletableFuture<Optional<ClassA>> classAFuture
        = CompletableFuture.supplyAsync(() -> Optional.ofNullable(service.getClassA())));
    
    CompletableFuture<Optional<ClassB>> classBFuture
        = CompletableFuture.supplyAsync(() -> Optional.ofNullable(service.getClassB()));
    
    CompletableFuture<Optional<ClassC>> classCFuture
        = CompletableFuture.supplyAsync(() -> Optional.ofNullable(service.getClassC()));
    
    return CompletableFuture.allOf(classAFuture, classBFuture, classCFuture)
         .thenApplyAsync(dummy -> {
            ClassD resultClass = new ClassD();
    
            classAFuture.join().ifPresent(resultClass::setClassA)
            classBFuture.join().ifPresent(resultClass::setClassB)
            classCFuture.join().ifPresent(resultClass::setClassC)
    
            return resultClass;
         });
    
    CompletableFuture类未来
    =CompletableFuture.SupplySync(()->可选.ofNullable(service.getClassA());
    完全未来类未来
    =CompletableFuture.SupplySync(()->可选.ofNullable(service.getClassB());
    完全未来类未来
    =CompletableFuture.supplyAsync(()->Optional.ofNullable(service.getClassC());
    返回CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
    .然后应用同步(虚拟->{
    ClassD resultClass=new ClassD();
    classAFuture.join().ifPresent(resultClass::setClassA)
    classBFuture.join().ifPresent(resultClass::setClassB)
    classCFuture.join().ifPresent(resultClass::setClassC)
    返回结果类;
    });
    
    如果您不想声明那么多的变量,另一种处理方法是使用Combine或CombineAsync将您的未来链接在一起

    public CompletableFuture<ClassD> getResultClassD()
    {
      return CompletableFuture.supplyAsync(ClassD::new)
        .thenCombine(CompletableFuture.supplyAsync(service::getClassA), (d, a) -> {
          d.setClassA(a);
          return d;
        })
        .thenCombine(CompletableFuture.supplyAsync(service::getClassB), (d, b) -> {
          d.setClassB(b);
          return d;
        })
        .thenCombine(CompletableFuture.supplyAsync(service::getClassC), (d, c) -> {
          d.setClassC(c);
          return d;
        });
    }
    
    public CompletableFuture getResultClassD()
    {
    返回CompletableFuture.SupplySync(ClassD::new)
    .thenCombine(CompletableFuture.SupplySync(服务::getClassA),(d,a)->{
    d、 setClassA(a);
    返回d;
    })
    .thenCombine(CompletableFuture.SupplySync(服务::getClassB),(d,b)->{
    d、 setClassB(b);
    返回d;
    })
    .thenCombine(CompletableFuture.supplyAsync(服务::getClassC),(d,c)->{
    d、 SETC(c);
    返回d;
    });
    }
    
    getter仍将异步启动,结果将被执行
        public class CombindFunctionImpl implement CombindFunction {
        public ABCData combind (ClassA a, ClassB b, ClassC c) {
            return new ABCData(a, b, c);
       }
    }
    
        public class FutureProvider {
    public CompletableFuture<ClassA> retrieveClassA() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new ClassA();
        });
    }
    
    public CompletableFuture<ClassB> retrieveClassB() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new ClassB();
        });
    }
    public CompletableFuture<ClassC> retrieveClassC() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new ClassC();
        });
    }
    }
    
    public static void main (String[] args){
        CompletableFuture<ClassA> classAfuture = futureProvider.retrieveClassA();
        CompletableFuture<ClassB> classBfuture = futureProvider.retrieveClassB();
        CompletableFuture<ClassC> classCfuture = futureProvider.retrieveClassC();
    
        System.out.println("starting completable futures ...");
        long startTime = System.nanoTime();
    
        ABCData ABCData = CompletableFuture.allOf(classAfuture, classBfuture, classCfuture)
                .thenApplyAsync(ignored ->
                        combineFunction.combind(
                                classAfuture.join(),
                                classBfuture.join(),
                                classCfuture.join())
                ).join();
    
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        System.out.println("completable futures are complete...");
        System.out.println("duration:\t" + Duration.ofNanos(duration).toString());
        System.out.println("result:\t" + ABCData);
    }