У меня есть функция, которая возвращает Try
, и я хочу запустить несколько ее экземпляров параллельно, но я не знаю, как это сделать - мне кажется, что я могу запустить только одинпосле другого.
Контекст: эта функция предназначена для получения блокировки, так что, если несколько потоков / рабочих работают параллельно, они не читают друг друга.В тестах я хочу запустить пять экземпляров одновременно и утверждать, что все, кроме одного, были заблокированы.Это работало, когда функция возвращала Future, но я провел некоторый рефакторинг, и теперь он возвращает Try, и тест перестал работать.
Поведение не похоже на код блокировки- кажется, я просто не понимаю параллелизма!
Я пытался использовать Future.fromTry
и выполнять их параллельно.Например:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.{Success, Try}
object Main extends App {
def greet(name: String): Try[Unit] = Try {
println(s"Hello $name!")
Thread.sleep(1000)
println(s"Goodbye $name!")
()
}
Seq("alice", "bob", "carol", "dave", "eve").map { name =>
Future.fromTry { greet(name) }
}
}
Я бы ожидал увидеть все сообщения «Hello», а затем все сообщения «Goodbye» - вместо этого кажется, что они выполняются один за другим.
Hello alice!
Goodbye alice!
Hello bob!
Goodbye bob!
Hello carol!
Goodbye carol!
Hello dave!
Goodbye dave!
Hello eve!
Goodbye eve!
Я осмотрелся и нашел предложения по настройке ExecutionContext и добавлению параллелизма - дело в том, что эта среда кажется совершенно счастливой для параллельного запуска Futures.
На той же машине с той же глобальнойExecutionContext, если я настраиваю функцию, чтобы она возвращала Future, а не Try, я вижу ожидаемый результат, и кажется, что функции работают параллельно.
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.{Success, Try}
object Main extends App {
def greet(name: String): Future[Unit] = Future {
println(s"Hello $name!")
Thread.sleep(1000)
println(s"Goodbye $name!")
()
}
Seq("faythe", "grace", "heidi", "ivan", "judy").map { name =>
greet(name)
}
Thread.sleep(2000) // Let the futures finish
}
Hello faythe!
Hello ivan!
Hello grace!
Hello judy!
Hello heidi!
Goodbye ivan!
Goodbye grace!
Goodbye heidi!
Goodbye judy!
Goodbye faythe!
Что яделать неправильно с Future.fromTry
, что означает, что он ожидает фьючерса, чтобы закончить?Как мне сделать так, чтобы он соответствовал второму примеру?
Или я полностью лаю не то дерево?