使用SingleScheduler从多个线程调用RxJava2 PublishSubject订阅服务器时,无法接收项目
在下面的单元测试中,我尝试从不同的线程发送10个使用SingleScheduler从多个线程调用RxJava2 PublishSubject订阅服务器时,无法接收项目,java,multithreading,kotlin,rx-java2,Java,Multithreading,Kotlin,Rx Java2,在下面的单元测试中,我尝试从不同的线程发送10个Strings,并测试是否从单个线程接收这些Strings。我的问题是这个测试失败了。有时它成功了,但有时我只收到8或9项,然后测试将挂起,直到闩锁超时。我是否以错误的方式使用了SingleScheduler?我错过什么了吗 val consumerCallerThreadNames = mutableSetOf<String>() val messageCount = AtomicInteger(0) val latch = Cou
String
s,并测试是否从单个线程接收这些String
s。我的问题是这个测试失败了。有时它成功了,但有时我只收到8
或9
项,然后测试将挂起,直到闩锁超时。我是否以错误的方式使用了SingleScheduler
?我错过什么了吗
val consumerCallerThreadNames = mutableSetOf<String>()
val messageCount = AtomicInteger(0)
val latch = CountDownLatch(MESSAGE_COUNT)
@Test
fun someTest() {
val msg = "foo"
val subject = PublishSubject.create<String>()
subject
.observeOn(SingleScheduler())
.subscribe({ message ->
consumerCallerThreadNames.add(Thread.currentThread().name)
messageCount.incrementAndGet()
latch.countDown()
}, Throwable::printStackTrace)
1.rangeTo(MESSAGE_COUNT).forEach {
Thread({
try {
subject.onNext(msg)
} catch (t: Throwable) {
t.printStackTrace()
}
}).start()
}
latch.await(10, SECONDS)
assertThat(consumerCallerThreadNames).hasSize(1)
assertThat(messageCount.get()).isEqualTo(MESSAGE_COUNT)
}
companion object {
val MESSAGE_COUNT = 10
}
val consumerCallerThreadNames=mutableSetOf()
val messageCount=AtomicInteger(0)
val latch=倒计时闩锁(消息计数)
@试验
有趣的测试{
val msg=“foo”
val subject=PublishSubject.create()
主题
.observeOn(SingleScheduler())
.subscribe({message->
consumerCallerThreadNames.add(Thread.currentThread().name)
messageCount.incrementAndGet()
倒数计时
},Throwable::printStackTrace)
1.rangeTo(消息计数)。forEach{
线({
试一试{
subject.onNext(msg)
}捕获(t:可丢弃){
t、 printStackTrace()
}
}).start()
}
等待(10秒)
assertThat(consumerCallerThreadNames).hasSize(1)
assertThat(messageCount.get()).isEqualTo(MESSAGE\u COUNT)
}
伴星{
val消息计数=10
}
如果我重写此代码以使用单线程执行器服务,测试将不再进行,因此问题可能是Rx或我缺乏Rx知识。RxJava要求在*上调用
不会同时发生。这意味着您的代码不是线程安全的
因为只有主题本身是以并发方式使用的,所以它应该可以通过使用subject.toSerialized()
方法序列化(本质上是Java的“同步”)主题本身来修复
val subject=PublishSubject.create()
变为val subject=PublishSubject.create().toSerialized()RxJava要求对*
的调用不能同时发生。这意味着您的代码不是线程安全的
因为只有主题本身是以并发方式使用的,所以它应该可以通过使用subject.toSerialized()
方法序列化(本质上是Java的“同步”)主题本身来修复
val subject=PublishSubject.create()
变为val subject=PublishSubject.create().toSerialized()
您所说的同时是什么意思?我不能连续快速地呼叫下一个?这意味着Rx本身不是线程安全的。在现实生活中,可能会发生两个用户同时单击一个按钮的情况,例如,我通过这种方式得到两个onNext
s。Rx规定,任何调用Observer
接口的人都必须确保没有并发调用。为了支持不可能的情况,有toSerialized()
运算符以一定的开销强制执行它。您所说的同时
是什么意思?我不能连续快速地呼叫下一个?这意味着Rx本身不是线程安全的。在现实生活中,可能会发生两个用户同时单击一个按钮的情况,例如,我通过这种方式得到两个onNext
s。Rx规定,任何调用Observer
接口的人都必须确保没有并发调用。为了支持不可能的情况,有toSerialized()
操作符以一定的开销强制执行它。