Это результат действия Future(…)
и flatMap
:
val future = Future(task)
запускает задачу параллельно
future.flatMap(result => task)
организует запуск task
, когда future
завершает
Обратите внимание, что future.flatMap(result => task)
не может запустить параллельное выполнение задачи до завершения future
, потому что для запуска task
нам нужен result
, который доступен только после завершения future
.
Теперь давайте посмотрим на ваш example1
:
def experiment1: Int = {
// construct three independent tasks and start running them
val f1 = task(1)
val f2 = task(2)
val f3 = task(3)
// construct one complicated task that is ...
val computation =
// ... waiting for f1 and then ...
f1.flatMap(r1 =>
// ... waiting for f2 and then ...
f2.flatMap(r2 =>
// ... waiting for f3 and then ...
f3.map(r3 =>
// ... adding some numbers.
r1 + r2 + r3)))
// now actually trigger all the waiting
Await.result(computation, Duration.Inf)
}
Таким образом, в example1
, поскольку все три задачи занимают одно и то же время и были запущены в одно и то же время, нам, вероятно, придется блокировать только при ожидании f1
. Когда мы подходим к ожиданию f2
, его результат уже должен быть.
Теперь, чем отличается example2
? 1032 *
def experiment2: Int = {
// construct one complicated task that is ...
val computation =
// ... starting task1 and then waiting for it and then ...
task(1).flatMap(r1 =>
// ... starting task2 and then waiting for it and then ...
task(2).flatMap(r2 =>
// ... starting task3 and then waiting for it and then ...
task(3).map(r3 =>
// ... adding some numbers.
r1 + r2 + r3)))
// now actually trigger all the waiting and the starting of tasks
Await.result(computation, Duration.Inf)
}
В этом примере мы даже не создаем task(2)
до того, как дождались завершения task(1)
, поэтому задачи не могут выполняться параллельно.
Таким образом, при программировании с помощью Scala Future
вы должны контролировать свой параллелизм, правильно выбирая код типа example1
и код типа example2
. Или вы можете посмотреть библиотеки, которые обеспечивают более явный контроль над параллелизмом.