Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
并行计算的RxJava排序输出_Java_Multithreading_Reactive Programming_Rx Java - Fatal编程技术网

并行计算的RxJava排序输出

并行计算的RxJava排序输出,java,multithreading,reactive-programming,rx-java,Java,Multithreading,Reactive Programming,Rx Java,我有一个要并行执行的任务列表,但我希望以与原始列表相同的顺序显示任务的结果。 换句话说,如果我有任务列表[A,B,C],我不希望在显示A-result之前显示B-result,但也不希望等到A-task完成后再开始B-task 此外,我希望尽快显示每个结果,换句话说,如果任务按顺序B、A、C完成,我不希望在收到B-result时显示任何内容,然后在收到A-result后立即显示A-result,然后在收到C-result时显示C-result 通过为每个任务创建一个可观察的对象,将它们与merg

我有一个要并行执行的任务列表,但我希望以与原始列表相同的顺序显示任务的结果。 换句话说,如果我有任务列表[A,B,C],我不希望在显示A-result之前显示B-result,但也不希望等到A-task完成后再开始B-task

此外,我希望尽快显示每个结果,换句话说,如果任务按顺序B、A、C完成,我不希望在收到B-result时显示任何内容,然后在收到A-result后立即显示A-result,然后在收到C-result时显示C-result

通过为每个任务创建一个可观察的对象,将它们与merge结合起来,订阅一个计算线程池,然后编写一个订阅服务器,该订阅服务器保存一个缓冲区,用于存储无序接收的任何结果,这当然不是很难做到。然而,Rx的经验法则往往是“已经有了一个这样的操作符”,所以问题是“什么是解决这个问题的正确RxJava方法?”如果确实有这样的事情的话。

“没有一个这样的操作符”。尽管如此,在1.0.15-SNAPSHOT版本中有一个实验性的
concatEagar()
操作符,听起来像是在做你想要的事情

如果您想推出自己的临时解决方案,直到
concatEager()
获得批准。您可以尝试以下方法:

public Observable<Result> concatEager(final Observable<Result> taskA, final Observable<Result> taskB, final Observable<Result> taskC) {
    return Observable
            .create(subscriber -> {
                final Observable<Result> taskACached = taskA.cache();
                final Observable<Result> taskBCached = taskB.cache();
                final Observable<Result> taskCCached = taskC.cache();

                // Kick off all the tasks simultaneously.
                subscriber.add(
                        Observable
                                .merge(taskACached, taskBCached, taskCCached)
                                .subscribe(
                                        result -> {     // Throw away result
                                        },
                                        throwable -> {  // Ignore errors
                                        }
                                )
                );

                // Put the results in order.
                subscriber.add(
                        Observable
                                .concat(taskACached, taskBCached, taskCCached)
                                .subscribe(subscriber)
                );
            });
}
public observatable concateger(最终可观测任务A、最终可观测任务B、最终可观测任务C){
可观测回波
.创建(订阅服务器->{
最终可观察到的taskacache=taskA.cache();
最终可观察到的taskBCached=taskB.cache();
最终可观察到的taskCache=taskC.cache();
//同时开始所有的任务。
订阅服务器。添加(
可观察
.merge(taskACached、taskBCached、taskCCached)
.订阅(
结果->{//丢弃结果
},
可丢弃->{//忽略错误
}
)
);
//把结果整理好。
订阅服务器。添加(
可观察
.concat(taskaccached,taskbccached,taskCCached)
.订阅(订户)
);
});
}

请注意,上面的代码完全未经测试。也许有更好的方法可以做到这一点,但这是我们首先想到的…

似乎您需要
concatEager
来完成这项任务,但使用1.0.15之前的工具可以实现这一点,而不需要“创建”观测值。以下是一个例子:

Observable<Long> source1 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(10);
Observable<Long> source2 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(20);
Observable<Long> source3 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(15);

Observable<Observable<Long>> sources = Observable.just(source1, source2, source3);

sources.map(v -> {
    Observable<Long> c = v.cache();
    c.subscribe(); // to cache all
    return c;
})
.onBackpressureBuffer() // make sure all source started
.concatMap(v -> v)
.toBlocking()
.forEach(System.out::println);

谢谢你的回答;你和阿卡诺克的回答都满足了我的要求,并且指向了大致相同的方向。但是,只能有一个(可接受的答案)。因此,阿卡诺克指出了保留所有价值观的弱点,并提出了解决方案,这是打破僵局的关键。
Observable<Long> source1 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(10);
Observable<Long> source2 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(20);
Observable<Long> source3 = Observable.interval(100, 100, TimeUnit.MILLISECONDS).take(15);

Observable<Observable<Long>> sources = Observable.just(source1, source2, source3);

sources.map(v -> {
    Observable<Long> c = v.cache();
    c.subscribe(); // to cache all
    return c;
})
.onBackpressureBuffer() // make sure all source started
.concatMap(v -> v)
.toBlocking()
.forEach(System.out::println);
//...
sources.map(v -> {
    UnicastSubject<Long> subject = UnicastSubject.create();
    v.subscribe(subject);
    return subject;
})
//...