为什么不在主线程上不执行分支的子任务?

时间:2019-11-13 12:17:04

标签: scala functional-programming zio

我是zio的新手,所以我可能会想念一些东西。

zio依赖项:

  

编译组:“ dev.zio”,名称:“ zio_2.12”,版本:“ 1.0.0-RC16”

我有一个简单的示例:

import zio._

object Sample2 {
  def main(args: Array[String]): Unit = {
    val runtime = new DefaultRuntime {}

    val a = ZIO.effect {
      println(s"A - ${Thread.currentThread().getName}")
      Thread.sleep(1000)
      println(s"A - ${Thread.currentThread().getName}")
      println("Finish A")
      2
    }

    val b = ZIO.effect {
      println(s"B - ${Thread.currentThread().getName}")
      Thread.sleep(5000)
      println(s"B - ${Thread.currentThread().getName}")
      println("Finish B")
      2
    }

    val c = ZIO.effect {
      println(s"C - ${Thread.currentThread().getName}")
      Thread.sleep(3000)
      println(s"C - ${Thread.currentThread().getName}")
      println("Finish C")
      2
    }

//   example A
//    val r = for {
//      x <- a
//      y <- b
//    } yield c.map(_ * x * y)

//   example B    
val r = for {
  fiberX <- a.fork
  fiberY <- b.fork
  x <- fiberX.join
  y <- fiberY.join
  z <- c
} yield x * y * z  

    val result = runtime.unsafeRun(r)
    println(s"Result: $result")
  }
}

如果我运行示例A,那么所有效果将在预期的主线程上执行。

如果我运行示例B,则我希望效果A和B将在单独的线程(光纤)上执行,效果C-在主线程上执行。结果我得到了所有效果都是在单独的线程(光纤)上执行的。

这是正确的行为吗?是否可以返回主线程?

1 个答案:

答案 0 :(得分:2)

光纤不是线程。它们是在专用线程池之上运行的轻量级抽象。通常,您会在许多线程上运行许多光纤。

调用阻塞时,您需要使用专用的线程池,以便不阻塞其他光纤。当您使用ZIO.effectBlocking时,ZIO默认提供一个。

更多详细信息:https://zio.dev/docs/overview/overview_basic_concurrency#fibers