我是RxJava的新手,所以选择使用它,因为我认为它非常适合我的用例。
我想在无限的时间内观察到一些Integer
值。每当这些值之一发生变化(即事件)时,我都希望在另一个线程上调用其所有观察者。
由于观察时间长,我以为我需要使用BehaviorSubject
类(尽管起初我以为Observable
是我所需要的..看到我只需要“观察”) ,我可以使用subscribeOn()
方法来设置调度程序,从而实现在后台线程上调用订阅者:
private BehaviorSubject<Integer> rotationPositionSubject = BehaviorSubject.createDefault(getRotorPosition());
rotationPositionSubject.subscribeOn(scheduler);
我有一个rotate()
方法,用于更新rotationPositionSubject
,它将从主线程调用:
@Override
public synchronized int rotate()
{
final int newRotorPosition = super.rotate();
rotationPositionSubject.onNext(newRotorPosition);
return newRotorPosition;
}
但是,通过上面的代码,我发现订户是在“主”线程上调用的。检查subscribeOn()的文档:
返回:
修改了源ObservableSource,以便其订阅发生在指定的Scheduler上
由于我没有使用返回的ObservableSource,所以上面的代码无法工作,但是返回对象是Observable
,对我的应用程序没有用?
然后的问题是,如何使用RxJava长期观察任何对象并在后台线程上调用订阅服务器,或者RxJava是错误的选择?
答案 0 :(得分:0)
经过一番试验,似乎在使用 public static void streamingDataOperations(ClientSocket cs) throws InterruptedException, IOException{
// call - retrieve streaming data constantly from client server,
// and write a line in the csv file at a rate of 150 milliseconds
// using bufferedWriter and printWriter (print method).
// Note that the flush method of bufferedWriter is never called,
// I would assume the data is in fact being written in buffered memory
// not the actual file.
cs.reqStreamingData(output_file); // <- this method comes from client's API.
// I would like to another thread (aka data processing thread) which repeats itself every 15 minutes.
// I am aware I can do that by creating a class that extends TimeTask and fix a schedule
// Now when this thread runs, there are things I want to do.
// 1. flush last 15 minutes of data to the output_file (Note no synchronized statement method or statements are used here, hence no object is being locked.)
// 2. process the data in R
// 3. wait for the output in R to come back
// 4. clear file contents, so that it always store data that only occurs in the last 15 minutes
}
对象时需要格外小心,而且它们的用法并不像我从各种接口的名称推断出的那样明显。
作为证明我目前正在做的测试方法:
BehaviorSubject
这将导致不希望的结果:
对线程ID执行测试:1
在线程ID上调用onSubscribe():1
在线程ID上调用onNext():1
在线程ID上调用onNext():1以退出代码0结束的过程
(不需要,因为在主线程上调用了@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);
}
)
修改代码以使用从调用onNext()
返回的Observable
会得到相同的不良结果:
subscribeOn
结果:
对线程ID执行测试:1
在线程ID上调用onSubscribe():1
在线程ID上调用onNext():1
在线程ID上调用onNext():1以退出代码0结束的过程
但是使用@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);
}
方法确实可以达到预期的结果:
observeOn()
对线程ID执行测试:1
在线程ID上调用onSubscribe():1
onNext()调用了线程ID:13
onNext()调用了线程ID:13以退出代码0结束的过程
在所有示例中,我仍然使用@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);
}
对象来发起事件,并且我只是偶然发现这将提供期望的结果。
让我担心的是,我可能以不正确的方式使用BehaviorSubject
和Observable
,只是“碰巧”会给我正确的结果,即在后台线程上调用了订阅者。除非我在文档中的某个地方错过了它,否则如何使用这些对象来获得期望的结果似乎并不明显。