RXJava2阅读器Observable与并发订阅者

时间:2018-02-07 03:40:31

标签: java multithreading rx-java2

我试图在Observable<String>之外实现RXJava2 BufferedReader。到目前为止一切顺利:

public class Launcher {
    public static void main(String[] args) throws Exception {

        Process process = Runtime.getRuntime().exec("ls /tmp");
        BufferedReader reader = new BufferedReader (new InputStreamReader(process.getInputStream()));

        Observable source = Observable.create(emitter -> {
            String line = "";
            while (line != null) {
                line = reader.readLine();
                if (line == null)
                    break;
                System.out.println("Engine " + Thread.currentThread().getName() + " - " + line); //process line
                emitter.onNext(line);
            }
            emitter.onComplete();
        }).subscribeOn(Schedulers.newThread());

        source.subscribe(line -> System.out.println("UI 1   " + Thread.currentThread().getName() + " - " + line));
        source.subscribe(line -> System.out.println("UI 2   " + Thread.currentThread().getName() + " - " + line));

        TimeUnit.SECONDS.sleep(10);

    }
}

onSubscribe以并行方式通知订阅者。如果我没有弄错的话,这意味着create()中的lambda将为每个消费者并行执行。

因此,如果我有两个订阅者,每个订阅者都会获得读者的一半。 Thread-1调用readLine()获取一行Thread-2将不会获得,只是下一行。

这一切都有道理,但我必须遗漏一些东西,因为我无法弄清楚如何:

  1. 读取一个帖子中的行
  2. 同时通知所有订阅者 - 因此每个订阅者都获得所有行
  3. 我调查Subject s,试图链接Observable s,但仍然无法弄明白。

    编辑:我将示例更新为完整的可运行类。根据我的理解,问题是热与冷的Observables。好像文档说Observable.create(...)应该创建一个冷的,而我的代码显然表现得很热。

    后续问题:如果我添加了使其成为Observable<String>的类型参数,则onSubscribe调用会破坏代码,并且不会编译,因为它会返回{{1} }。为什么?在中间参数上调用Observable<Object>奇怪地起作用:

    onSubscribe

1 个答案:

答案 0 :(得分:0)

使用publish

ConnectableObservable<String> o = Observable.create(emitter -> {
    try (BufferedReader reader = ...) {
        while (!emitter.isDisposed()) {
            String line = reader.readLine();
            if (line == null || line.equals("end")) {
                emitter.onComplete();
                return;          
            }
            emitter.onNext(line);
        }
    }
}).subscribeOn(Schedulers.io())
  .publish();

o.subscribe(/* consumer 1 */);
o.subscribe(/* consumer 2 */);

o.connect();