Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SingleScheduler从多个线程调用RxJava2 PublishSubject订阅服务器时,无法接收项目_Java_Multithreading_Kotlin_Rx Java2 - Fatal编程技术网

使用SingleScheduler从多个线程调用RxJava2 PublishSubject订阅服务器时,无法接收项目

使用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

在下面的单元测试中,我尝试从不同的线程发送10个
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()
操作符以一定的开销强制执行它。