Почему разветвленная подзадача не выполняется не в основном потоке?
Я новичок в 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 ответ
Волокна - это не нити. Это легкая абстракция, работающая поверх выделенного пула потоков. Обычно у вас будет много волокон, работающих на меньшем количестве потоков.
Когда вы вызываете что-то блокирующее, вам нужно использовать выделенный пул потоков, чтобы не блокировать другие волокна. ZIO предоставляет его по умолчанию, когда вы используетеZIO.effectBlocking
.
Подробнее: https://zio.dev/docs/overview/overview_basic_concurrency