首页 > 解决方案 > 为什么不在主线程上执行分叉子任务?

问题描述

我是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 - 在主线程上。结果我得到所有效果都是在单独的线程(纤维)上执行的。

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

标签: scalafunctional-programmingzio

解决方案


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

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

更多细节:https ://zio.dev/docs/overview/overview_basic_concurrency#fibers


推荐阅读