monix:Task.executeWithFork阻止执行?

时间:2019-01-18 08:43:57

标签: scala monix

在以下示例中,我无法弄清楚为什么添加executeWithFork会阻止任务运行:

import java.util.concurrent.TimeUnit

import monix.execution.schedulers.SchedulerService
import monix.reactive.subjects.ConcurrentSubject

object Sandbox {

  def main(args: Array[String]): Unit = {
    implicit val scheduler: SchedulerService =
      monix.execution.Scheduler(java.util.concurrent.Executors.newCachedThreadPool())

    val input = ConcurrentSubject.publish[String]

    // prints nothing
    input.foreachL(println).executeWithFork.runAsync
    // this works:
    // input.foreachL(println).runAsync

    input.onNext("one")
    input.onNext("two")

    scheduler.shutdown()
    scheduler.awaitTermination(1, TimeUnit.MINUTES, monix.execution.Scheduler.Implicits.global)
  }
}

1 个答案:

答案 0 :(得分:1)

您看到的行为是两个事实的结果:

  1. 使用executeWithFork会给线程切换带来一些额外的延迟

  2. 您使用ConcurrentSubject.publish(例如,与replay相反)。如果您打开PublishSubject的文档,您可能会看到

  

PublishSubject仅向订户发出在订阅时间之后由源发出的那些项目。

换句话说,您在发布"one""two"的主线程与必须订阅input来获取数据的派生线程之间存在竞争条件。结果取决于哪个线程赢得竞争:订阅丢失之前发布的所有数据。在我的硬件中,我几乎总是看到"two",有时甚至看到"one",您的结果可能会有所不同。

最简单的测试方法是在第一个Thread.sleep(100)之前添加input.onNext,并且您应该每次都看到两个事件。您还可以尝试推动事件而不只是2个,以确保不会丢失所有内容。