如何使用RxJava 2创建异步事件总线?

时间:2018-05-08 23:04:42

标签: java multithreading rx-java rx-java2

使用RXJava 2,我正在尝试创建一个异步事件总线。

我有一个单独的对象,具有PublishSubject属性。发射器可以使用onNext在主题上向总线发送事件。

如果订阅者执行任务很长,我希望我的总线在多个线程上调度任务以同时执行任务。这意味着我希望在项目发布后立即开始项目的工作,即使前一项目的工作没有完成。

但是,即使将observeOnscheduler一起使用,我也无法同时运行我的任务。

示例代码:

public void test() throws Exception {
    Subject<Integer> busSubject = PublishSubject.<Integer>create().toSerialized();

    busSubject.observeOn(Schedulers.computation())
            .subscribe(new LongTaskConsumer());

    for (int i = 1; i < 5; i++) {
        System.out.println(i + " - event");
        busSubject.onNext(i);
        Thread.sleep(1000);
    }
    Thread.sleep(1000);
}

private static class LongTaskConsumer implements Consumer<Integer> {
    @Override
    public void accept(Integer i) throws Exception {
        System.out.println(i + " -   start work");
        System.out.println(i + " -     computation on thread " + Thread.currentThread().getName());
        Thread.sleep(2000);
        System.out.println(i + " -   end work");
    }
}

打印:

1 - event
1 -   start work
1 -     computation on thread RxComputationThreadPool-1
2 - event
3 - event
1 -   end work
2 -   start work
2 -     computation on thread RxComputationThreadPool-1
4 - event
2 -   end work
3 -   start work
3 -     computation on thread RxComputationThreadPool-1
3 -   end work
4 -   start work
4 -     computation on thread RxComputationThreadPool-1
4 -   end work

这意味着第2项的工作等待第1项的工作结束,即使事件2已经发出。

1 个答案:

答案 0 :(得分:1)

当下面的调用发生时,将从Schedulers.computation()创建一个工作程序,并将其用于整个流。这就是为什么您提交的所有工作都是在RxComputationThreadPool-1上完成的。

busSubject.observeOn(Schedulers.computation())
        .subscribe(new LongTaskConsumer());

安排多线程的工作:

busSubject.flatMap(x ->
        Flowable.just(x)
            .subscribeOn(Schedulers.computation()
            .doOnNext(somethingIntensive))
    .subscribe(new LongTaskConsumer());

另请注意,密集型工作是在flatMap内而非LongTaskConsumer内执行的,因为所有项目都会连续到达LongTaskConsumer

还有其他一些并行工作的方法,您可能需要根据PublishSubject发生的事件数进行调查。