在Java中,从两个并行执行的块中获取结果

时间:2018-03-19 01:52:18

标签: java multithreading spring-integration rx-java

研究这个问题有点困难,因为我不确定问题应该如何措辞。这里有一些伪代码总结了我的目标。

public class TestService {
    Object someBigMehtod(String A, Integer I) {
        {  //block A 
            //do some long database read
        }
        { //block B
            //do another long database read at the same time as block B
        }
        {  //block C
            //get in this block when both A & B are complete
            //and access result returned or pushed from A & B
            //to build up some data object to push out to a class that called
            //this service or has subscribed to it
            return null;
        }
    }
}

我在想我可以使用RxJava或Spring Integration来实现这一点,或者只是实例化多个线程并运行它们。只是它的布局虽然让我觉得Rx有解决方案,因为我认为数据被推到块C.提前感谢您可能有任何建议。

3 个答案:

答案 0 :(得分:3)

您可以使用CompletableFuture执行此操作。特别是它的thenCombine方法,它等待完成两个任务。

CompletableFuture<A> fa = CompletableFuture.supplyAsync(() -> {
    // do some long database read
    return a;
});

CompletableFuture<B> fb = CompletableFuture.supplyAsync(() -> {
    // do another long database read
    return b;
});

CompletableFuture<C> fc = fa.thenCombine(fb, (a, b) -> {
    // use a and b to build object c
    return c;
});

return fc.join();

这些方法都将在ForkJoinPool.commonPool()上执行。如果传入可选的Executors,则可以控制它们的运行位置。

答案 1 :(得分:0)

您可以使用 Rxjava 中的 Zip 运算符。此运算符可以并行运行多个进程,然后压缩结果。

一些文件http://reactivex.io/documentation/operators/zip.html

这里有一个如何运作https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/combining/ObservableZip.java

的例子

答案 2 :(得分:0)

现在我刚刚接受了John的建议。这是获得预期的效果。我混合了RxJava1和RxJava2语法,这可能是不好的做法。看起来我在java.util.concurrent包中为我提供了一些阅读材料。时间允许我想做拉链解决方案。

@Test
public void myBigFunction(){
    System.out.println("starting ");
    CompletableFuture<List<String>> fa =  CompletableFuture.supplyAsync( () ->
        {  //block A
            //do some long database read
            try {

                Thread.sleep(3000);
                System.out.println("part A");
                return asList(new String[] {"abc","def"});
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
    );

    CompletableFuture<List<Integer>> fb =  CompletableFuture.supplyAsync( () ->
            {  //block B
                //do some long database read
                try {
                    Thread.sleep(6000);
                    System.out.println("Part B");
                    return asList(new Integer[] {123,456});
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }
    );

    CompletableFuture<List<String>> fc = fa.thenCombine(fb,(a,b) ->{
        //block C
        //get in this block when both A & B are complete
        int sum = b.stream().mapToInt(i -> i.intValue()).sum();
        return a.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s+sum;
            }
        }).collect(Collectors.toList());
    });
    System.out.println(fc.join());
}

运行只需6秒钟。