RxJava并行执行问题

时间:2017-03-14 21:09:55

标签: multithreading rx-java

我正在尝试使用Rx Java进行并行化。我正在使用Rx Java并行调用5种方法,如下所示。

    public Map findData(param1,param2){

               Observable<List<DataDTO>> data1 = 
                            Observable.create(s->{
                                    try {   
                                        s.onNext(method1(param1,param2));
                                    }
                                    catch(Exception e) {
                                        System.out.println("Exception happened while calculating Data");
                                        s.onError(e);
                                    }

                        });

                        Observable<List<DataDTO>> data2 = 
                                Observable.create(s->{
                                        try {   
                                            s.onNext(method2(param1,param2));
                                        }
                                        catch(Exception e) {
                                            System.out.println("Exception happened while calculating Data");
                                            s.onError(e);
                                        }
                            });


                        Observable<List<DataDTO>> data3 = 
                                Observable.create(s->{
                                        try {   
                                            s.onNext(method3(param1,param2));
                                        }
                                        catch(Exception e) {
                                            System.out.println("Exception happened while calculating Data");
                                            s.onError(e);
                                        }
                            });

                        Observable<List<DataDTO>> data4 = 
                                Observable.create(s->{
                                        try {   
                                            s.onNext(method3(param1,param2));
                                        }
                                        catch(Exception e) {
                                            System.out.println("Exception happened while calculating Data");
                                            s.onError(e);
                                        }
                            });

                        Observable<List<DataDTO>> data5 = 
                                Observable.create(s->{
                                        try {   
                                            s.onNext(method4(param1,param2));
                                        }
                                        catch(Exception e) {
                                            System.out.println("Exception happened while calculating Data");
                                            s.onError(e);
                                        }
                            });

             Observable<List<DataDTO>> mergedBean = Observable.merge(
                         data1.subscribeOn(Schedulers.io()),
                    data2.subscribeOn(Schedulers.io()),
                    data3.subscribeOn(Schedulers.io()),
                    data4.subscribeOn(Schedulers.io()));

       Observable<List<DataDTO>> mergedBean1 = Observable.merge(mergedBean,data5.subscribeOn(Schedulers.io()));

  mergedBean1.subscribe(s->combineDataMethod(s,beanMap),
                        e ->   {throw new BusinessException(e);});

     System.out.println("Returning Map created beanMap="+beanMap);

         return beanMap;
    }

所有方法都是并行执行的,我正在按照预期的方式获取beanMap和组合数据。但问题是主线程在所有其他并行线程完成之前将beanMap返回给调用方法。所以它将空映射返回给调用者。在这里实施并行调用的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您需要将Observable转换为BlockingObservable

mergedBean1.toBlocking().subscribe(...);

这将等到源Observable完成。但是,为什么不简单地返回Observable<Map>?这样你就不需要明确地等待了,你可以用其他并行操作来组合它。

此外,您的代码应该或多或少等同于以下内容:

Observable.just(
     Observable.defer(() -> Observable.just(method1(param1,param2))),
     Observable.defer(() -> Observable.just(method1(param1,param2))),
     Observable.defer(() -> Observable.just(method1(param1,param2))),
     Observable.defer(() -> Observable.just(method1(param1,param2))),
     Observable.defer(() -> Observable.just(method1(param1,param2))),
     Observable.defer(() -> Observable.just(method1(param1,param2)))
)
.map(o -> o.subscribeOn(Schedulers.io()))
.compose(Observable::merge)
.doOnNext(s -> combineDataMethod(s,beanMap))
.doOnError(e -> System.out.println("Exception happened while calculating Data"))
.onErrorResumeNext(e -> Observable.error(new BusinessException(e)))
.toBlocking()
.subscribe();