Java BehaviorSubject在另一个线程上订阅

Java BehaviorSubject在另一个线程上订阅,java,reactive-programming,rx-java2,Java,Reactive Programming,Rx Java2,我是RxJava新手,我选择使用它是因为我认为它非常适合我的用例 我有一些Integer值,我想在无限的时间内观察它们。每当这些值中的一个发生变化时(即事件),我希望在另一个线程上调用它的所有观察者 由于需要较长的观察时间,我认为我需要使用BehaviorSubject类(虽然最初我认为Observable是我所需要的一切..因为我只需要“观察”),我可以使用subscribeOn()设置调度程序从而实现在后台线程上调用订阅者的方法: private BehaviorSubject<Int

我是RxJava新手,我选择使用它是因为我认为它非常适合我的用例

我有一些
Integer
值,我想在无限的时间内观察它们。每当这些值中的一个发生变化时(即事件),我希望在另一个线程上调用它的所有观察者

由于需要较长的观察时间,我认为我需要使用
BehaviorSubject
类(虽然最初我认为
Observable
是我所需要的一切..因为我只需要“观察”),我可以使用
subscribeOn()
设置调度程序从而实现在后台线程上调用订阅者的方法:

private BehaviorSubject<Integer> rotationPositionSubject = BehaviorSubject.createDefault(getRotorPosition());
rotationPositionSubject.subscribeOn(scheduler);
然而,通过上面的代码,我发现订阅服务器是在“主”线程上调用的。检查文档以了解:

返回:

已修改源ObservableSource,以便其订阅发生在指定的计划程序上

所以我上面的代码不起作用,因为我没有使用返回的ObservableSource,但是返回的对象是一个
Observable
,它对我的应用程序没有用处


问题是,我如何在RxJava的后台线程上长期观察任何对象和调用订阅者,还是RxJava是一个错误的选择?

经过一些实验后,在使用
行为主体
对象时,人们似乎需要一些注意,它们的使用并不像我从各种接口的名称中推断的那样明显

作为证明我目前所做工作的测试方法:

@Test
public void test()
{
    System.out.println("Executing test on thread ID: " + Thread.currentThread().getId());
    final BehaviorSubject<Integer> rotorBehaviour = BehaviorSubject.create();
    rotorBehaviour.subscribeOn(Schedulers.single());
    rotorBehaviour.subscribe(new Observer<Integer>()
    {
        @Override
        public void onSubscribe(final Disposable d)
        {
            System.out.println("onSubscribe() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onNext(final Integer integer)
        {
            System.out.println("onNext() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onError(final Throwable e)
        {
            System.out.println("onError() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onComplete()
        {
            System.out.println("onComplete() called on thread ID: " + Thread.currentThread().getId());
        }
    });


    rotorBehaviour.onNext(1);
    rotorBehaviour.onNext(2);

}
结果:

对线程ID:1执行测试
对线程ID:1调用onSubscribe()
对线程ID:1调用onNext()
在线程ID为1时调用了onNext()

进程已完成,退出代码为0

但是,使用
observeOn()
方法确实会得到所需的结果:

@Test
public void test()
{
    System.out.println("Executing test on thread ID: " + Thread.currentThread().getId());
    final BehaviorSubject<Integer> rotorBehaviour = BehaviorSubject.create();
    Observable<Integer> rotorObservable = rotorBehaviour.subscribeOn(Schedulers.single());

    rotorObservable.subscribe(new Observer<Integer>()
    {
        @Override
        public void onSubscribe(final Disposable d)
        {
            System.out.println("onSubscribe() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onNext(final Integer integer)
        {
            System.out.println("onNext() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onError(final Throwable e)
        {
            System.out.println("onError() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onComplete()
        {
            System.out.println("onComplete() called on thread ID: " + Thread.currentThread().getId());
        }
    });
    rotorBehaviour.onNext(1);
    rotorBehaviour.onNext(2);
}
@Test
public void test()
{
    System.out.println("Executing test on thread ID: " + Thread.currentThread().getId());
    final BehaviorSubject<Integer> rotorBehaviour = BehaviorSubject.create();
    Observable<Integer>rotorObservable = rotorBehaviour.observeOn(Schedulers.single());

    rotorObservable.subscribe(new Observer<Integer>()
    {
        @Override
        public void onSubscribe(final Disposable d)
        {
            System.out.println("onSubscribe() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onNext(final Integer integer)
        {
            System.out.println("onNext() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onError(final Throwable e)
        {
            System.out.println("onError() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onComplete()
        {
            System.out.println("onComplete() called on thread ID: " + Thread.currentThread().getId());
        }
    });
    rotorBehaviour.onNext(1);
    rotorBehaviour.onNext(2);
}
@测试
公开无效测试()
{
System.out.println(“对线程ID执行测试:+thread.currentThread().getId());
最终行为主体行为=行为主体。创建();
ObserverTorObservable=RotorBehavior.observeOn(Schedulers.single());
rotorObservable.subscribe(新观察者()
{
@凌驾
公开认购无效(最终可处置d)
{
System.out.println(“在线程ID上调用onSubscribe():+thread.currentThread().getId());
}
@凌驾
public void onNext(最终整数)
{
System.out.println(“对线程ID调用onNext()”+thread.currentThread().getId());
}
@凌驾
公共作废申报人(最终可丢弃e)
{
System.out.println(“对线程ID调用了onError()”+thread.currentThread().getId());
}
@凌驾
未完成的公共空间()
{
System.out.println(“对线程ID调用了onComplete():+thread.currentThread().getId());
}
});
RotorBehavior.onNext(1);
RotorBehavior.onNext(2);
}
对线程ID:1执行测试
对线程ID:1调用onSubscribe()
对线程ID:13调用了onNext()
对线程ID:13调用了onNext()

进程已完成,退出代码为0

同样,在所有的例子中,我仍然使用
BehaviorSubject
对象来启动一个事件,我只是意外地发现这将给出期望的结果


我担心的是,我可能以一种不正确的方式使用了
Observable
BehaviorSubject
,这只是“碰巧”给了我正确的结果,即在后台线程上调用订阅者。除非我在文档中遗漏了它,否则如何使用这些对象来获得所需的结果似乎并不明显。

您能提供一个解决方案吗?还有一个
observeOn()
您可以使用。您正在使用
Observable
对象使用其
subscribe()
方法对新值作出反应。@Progman我已添加到该方法中,以显示如何使用
rotationPositionSubject
observeOn()
还返回和
observeable
,这使我处于与上面所述相同的位置。请显示从
主题中读取值的代码。不使用
Observable
对象听起来很奇怪,因为必须将它用于
subscribe()
方法才能从源代码获取数据。无论如何,方法
observeOn()
subscribeOn()
应该切换线程。如果没有,请提供。a
BehaviorSubject
用于订阅时应始终返回值的主题。您将获得添加的“最后”值。
Observable
是通过使用
subscribe()
生成的订阅从源获取值的默认方式。方法
observeOn()
指定了一个线程(池),侦听器应该在该线程中运行,否则“消息”将在该线程上发送/处理,而该线程执行了
onNext()
调用。我不太确定您的观点。我想要实现的就是“观察”一个对象,在我的例子中是一个
整数
,时间是不确定的,当它改变时(通过从主线程改变),我希望所有订阅者/观察者(我在这里互换使用这些术语,因为我不清楚区别)在后台线程上被“调用”。我认为我已经以一种直观的方式使用了这些接口(基于它们的名称),但看起来RxJava并不像我希望的那样直截了当。如果你有一个我想要实现的例子,我很想看看。订阅者/观察者使用
subscribe()
方法在
Observable
对象上注册自己。更改原始源时(通过onNext()调用或通过一些复杂的subsc
@Test
public void test()
{
    System.out.println("Executing test on thread ID: " + Thread.currentThread().getId());
    final BehaviorSubject<Integer> rotorBehaviour = BehaviorSubject.create();
    Observable<Integer>rotorObservable = rotorBehaviour.observeOn(Schedulers.single());

    rotorObservable.subscribe(new Observer<Integer>()
    {
        @Override
        public void onSubscribe(final Disposable d)
        {
            System.out.println("onSubscribe() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onNext(final Integer integer)
        {
            System.out.println("onNext() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onError(final Throwable e)
        {
            System.out.println("onError() called on thread ID: " + Thread.currentThread().getId());
        }

        @Override
        public void onComplete()
        {
            System.out.println("onComplete() called on thread ID: " + Thread.currentThread().getId());
        }
    });
    rotorBehaviour.onNext(1);
    rotorBehaviour.onNext(2);
}