RxJava:如何创建rx.Single / rx.Observable的任务图/工作流?

时间:2018-09-18 12:09:07

标签: observable rx-java workflow directed-acyclic-graphs

我有rx.Singles(或rx.Observables),它们将按照此DAG(有向非循环图)中所示的依赖关系顺序执行:

Singles Dependency Graph

  • one应该先执行
  • twothree仅在one完成后才执行
  • twothree可以并行运行
  • four仅应在two完成后执行
  • five仅在twothree完成后才执行
  • fourfive可以并行运行
  • six应该在fourfive之后最后执行。

我们如何才能最好地实现这一目标?

以下解决方案(解决方案#1 )可以正常运行:

package rxtest;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;


public class ObservablesDagTest {
    private static final Logger logger = LoggerFactory.getLogger(ObservablesDagTest.class);
    private static Executor customExecutor = Executors.newFixedThreadPool(20);

    @Test
    public void dagTest() {
        Single<Integer> one = createSingle(1, 100);
        Single<Integer> two = createSingle(2, 200);
        Single<Integer> three = createSingle(3, 500);
        Single<Integer> four = createSingle(4, 400);
        Single<Integer> five = createSingle(5, 200);
        Single<Integer> six = createSingle(6, 150);

        executeDag(one, two, three, four, five, six);
    }

    private void executeDag(Single<Integer> one, Single<Integer> two, Single<Integer> three, Single<Integer> four,
            Single<Integer> five, Single<Integer> six) {
        logger.info("BEGIN");

        Single<Integer> twoCached = two.toObservable().cache().toSingle();

        Observable.concat(
                one.toObservable(),
                Observable.merge(
                        Single.concat(twoCached, four),
                        Observable.concat(Single.merge(twoCached, three), five.toObservable())),
                six.toObservable())
                .toBlocking()
                .subscribe(i -> logger.info("Received : " + i));

        logger.info("END");
    }

    private Single<Integer> createSingle(int j, int sleepMs) {
        Single<Integer> single = Single.just(j)
                .flatMap(i -> Single.<Integer> create(s -> {
                    logger.info("onSubscribe : {}", i);
                    sleep(sleepMs);
                    s.onSuccess(i);
                }).subscribeOn(Schedulers.from(customExecutor)));
        return single;
    }

    private void sleep(int ms) {
        try {
            Thread.sleep(ms);
        }
        catch (InterruptedException e) {
        }
    }
}

输出

21:16:23.879 [main] INFO rxtest.ObservablesDagTest BEGIN
21:16:23.974 [pool-1-thread-1] INFO rxtest.ObservablesDagTest onSubscribe : 1
21:16:24.079 [main] INFO rxtest.ObservablesDagTest Received : 1
21:16:24.101 [pool-1-thread-3] INFO rxtest.ObservablesDagTest onSubscribe : 3
21:16:24.101 [pool-1-thread-2] INFO rxtest.ObservablesDagTest onSubscribe : 2
21:16:24.303 [main] INFO rxtest.ObservablesDagTest Received : 2
21:16:24.303 [main] INFO rxtest.ObservablesDagTest Received : 2
21:16:24.304 [pool-1-thread-4] INFO rxtest.ObservablesDagTest onSubscribe : 4
21:16:24.602 [main] INFO rxtest.ObservablesDagTest Received : 3
21:16:24.603 [pool-1-thread-5] INFO rxtest.ObservablesDagTest onSubscribe : 5
21:16:24.704 [main] INFO rxtest.ObservablesDagTest Received : 4
21:16:24.804 [main] INFO rxtest.ObservablesDagTest Received : 5
21:16:24.805 [pool-1-thread-6] INFO rxtest.ObservablesDagTest onSubscribe : 6
21:16:24.956 [main] INFO rxtest.ObservablesDagTest Received : 6
21:16:24.956 [main] INFO rxtest.ObservablesDagTest END

是否有比此更有效/流利的解决方案?

0 个答案:

没有答案