这是我的示例代码
Observable.range(1,5)
.subscribeOn(Schedulers.computation())
.map(Observables05::doSomething)
.subscribe(System.out::println, Throwable::printStackTrace, () -> System.out.println("done"));
我的doSomething方法是,
public static int doSomething(int i) {
try {
System.out.println("Processing " + i +
" on Thread -- " + Thread.currentThread().getName());
Thread.sleep(500);
return i;
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
仅使用主线程中的示例代码退出程序。但是,如果在此之后使用Thread.sleep(3000)
,则程序在睡眠时间结束时退出之前正常工作。
这是预期的行为吗?为什么?如何在不使用Thread.sleep
的情况下运行此代码?
答案 0 :(得分:3)
subscribeOn
安排subscribe
调用后台线程(您选择了computation
调度程序)。在此计划之后,您的主线程可以自由运行,即终止您的程序。
不知何故,您需要等待所有理想的任务完成才能退出。 Thread.sleep(3000)
为简单的测试用例完成工作。
真正的程序通常不会那么快地终止。仍然存在需要等待某个后台任务完成的情况。您可以使用各种线程同步机制(例如CountDownLatch
)。
答案 1 :(得分:0)
如果您想测试您编写的代码,请使用TestSubscriber。
代码看起来像这样:
TestSubscriber<Integer> testSubscriber = new TestSubscriber<>();
Observable.range(1,5)
.subscribeOn(Schedulers.computation())
.map(Observables05::doSomething)
.subscribe(testSubscriber);
testSubscriber.awaitTerminalEvent(10, TimeUnit.SECONDS);
请记住,TestSubscriber
允许您测试的不仅仅是终端事件。
答案 2 :(得分:0)
这是预期的行为。您在main
方法中执行时的简单解决方案是在订阅之前使用toBlocking()
- 如下所示 -
Observable.range(1,5)
.subscribeOn(Schedulers.computation())
.map(DummyJunk::doSomething)
.toBlocking()
.subscribe(System.out::println, Throwable::printStackTrace, () -> System.out.println("done"));