Java 订阅主题时的奇怪TestObserver行为

Java 订阅主题时的奇怪TestObserver行为,java,kotlin,rx-java,rx-java2,Java,Kotlin,Rx Java,Rx Java2,考虑Kotlin中的以下RxJava 2代码段: //1。创建主题 val subject=PublishSubject.create() // 2. 可观察 val observable=subject.subscribeOn(Schedulers.io()) // 3. 订阅 val observer=可观察的。测试() // 4. 触发下一个 主题.onNext(42) // 5. 等待 观察员人数(1) // 6. 断言值 观察员资产价值(42) 根据我的理解,observer应该能够

考虑Kotlin中的以下RxJava 2代码段:

//1。创建主题
val subject=PublishSubject.create()
// 2. 可观察
val observable=subject.subscribeOn(Schedulers.io())
// 3. 订阅
val observer=可观察的。测试()
// 4. 触发下一个
主题.onNext(42)
// 5. 等待
观察员人数(1)
// 6. 断言值
观察员资产价值(42)
根据我的理解,
observer
应该能够在等待语句5之后接收到
42
,并且对语句6的断言应该成功

然而,实际发生的情况是:5阻塞直到超时,因为没有收到任何值,并且6上的断言失败

另外,如果我在3上设置一个断点,然后在暂停后继续执行,那么一切都会正常工作。看起来像是线程问题


我显然遗漏了一些东西。使用热可观察对象的正确方法是什么?

通过取消订阅,您将对
主题
的实际订阅放在另一个线程上,这可能需要更长的时间,以便
主题.onNext(42)
仍能找到未订阅的
主题

除了在
PublishSubject
上使用
subscribeOn
没有实际用途之外,您可以通过循环一点来等待订阅:

while (!subject.hasObservers()) { Thread.sleep(1); }

你是对的。我将编辑这个问题这是有意义的,尽管我承认我希望订阅和发布在内部同步。在我的特殊情况下,我无法控制1和2。我只是在使用一个外部库提供的热观测值,它恰好在IO调度程序线程上发出。在我将您的答案标记为已接受之前,您是否认为有更好的方法来完成此任务,而不使用奇怪的
while
循环?通过使用2,API提供程序已明确选择不使用任何同步化行为,因此您必须使他/她不使用
订阅
while (!subject.hasObservers()) { Thread.sleep(1); }