Rxjava:订阅特定的帖子

时间:2015-11-06 06:47:42

标签: multithreading rx-java subscriber

我是Rxjava的新手。 我有以下代码:

    System.out.println("1: " + Thread.currentThread().getId());
    Observable.create(new rx.Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subcriber) {
            System.out.println("2: " + Thread.currentThread().getId());
            // query database
            String result = ....
            subcriber.onNext(result);
        }

    }).subscribeOn(Schedulers.newThread()).subscribe(countResult -> {
        System.out.println("3: " + Thread.currentThread().getId());
    });

例如,输出将为:

1:50
2:100
3:100

我希望订阅者在ID为50的线程上运行。我该怎么做?

5 个答案:

答案 0 :(得分:1)

我认为有两种情况。您需要它在UI线程上运行,或者是因为同步。我知道你不能在特定的线程上调用一个函数,因为当调用该方法时它被绑定到线程的上下文,所以不可能从一个线程调用一个方法到另一个线程。您的问题是订阅方中的方法是从Schedulers.newThread()调用的。我还发现了github issue关于Schedulers.currentThread()的问题。您需要的是在调用观察者时通知调用者线程。

你也可以使用akka,用它来编写并发代码就更简单了。

抱歉我的语法不好。

答案 1 :(得分:0)

来自docs

  

默认情况下,Observable和您应用的运算符链   它将完成其工作,并将在同一个线程上通知其观察员   调用其Subscribe方法。 SubscribeOn运算符   通过指定其中的不同调度程序来更改此行为   Observable应该运行。 ObserveOn运算符指定了一个   Observable将用于发送通知的不同Scheduler   对观察员来说。

因此,您可以使用subscribe代替 subscribeOn 在您创建的同一个帖子上观察您的收藏,如下所示:

Observable.create(new rx.Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subcriber) {
            System.out.println("2: " + Thread.currentThread().getId());
            // query database
            String result = ....
            subcriber.onNext(result);
        }

    }).subscribe(countResult -> {
        System.out.println("3: " + Thread.currentThread().getId());
    });

<强>更新 如果您的应用程序是Android应用程序,您可以像在后台线程上一样使用subscribe,并使用Handler消息将结果传递给主线程。

如果您的应用程序是Java应用程序,我可能会建议使用wait()和notify()机制,或者考虑使用EventBus或akka等框架来处理更复杂的场景。

答案 2 :(得分:-1)

使用RxJava 1.0.15,您可以在toBlocking()之前应用subscribe,并且所有内容都将在创建整个运算符序列的线程上运行。

答案 3 :(得分:-1)

所以subscribeOn表示Observable将开始发出项目的线程,observeOn&#34; switch&#34;到可观察链的其余部分的线程。在订阅之前放置一个observeOn(schedulers.CurrentThread()),你将在创建此observable的线程中而不是在它执行的线程中。这里有一个解释rxjava线程的资源好。 http://www.grahamlea.com/2014/07/rxjava-threading-examples/

答案 4 :(得分:-1)

我相信@akarnokd是对的。您可以在没有.subscribeOn(Schedulers.newThread())的情况下运行,以便它同步发生或在订阅之前使用toBlocking()。或者,如果您只想在同一个线程上发生所有事情,但它不一定是当前线程,那么您可以这样做:

Observable
    .defer(() -> Observable.create(...))
    .subscribeOn(Schedulers.newThread())
    .subscribe(subscriber);

defer确保在订阅线程上发生对create的调用。