Работа со списком при помощи Future
Имеется список из 5000 элементов. Хочу распараллелить процесс обработки списка через Future. Один из вариантов, который я пробовал - это выполнение через Future в каждой итерации. В качестве ExecutorContext я использовал fixedThreadPool(10). Код вида
val list = List("Ivan", "Sergey", "Victor")
for(name <- list) {
Future { //do something with name }
}
обрабатывает не корректно. При попытке добавить каждый name а базу - добавляется малая часть всего списка. Вероятно, это происходит из-за того, что я не дожидаюсь выполнения Future. Почему так происходит и как правильно распараллелить работу над списком? Спасибо.
Ответы (1 шт):
Верно, Future у тебя создаются и выполняются в отдельном потоке. Нужен Await который будет ждать их в основном потоке.
val list = List("Ivan", "Sergey", "Victor")
import scala.concurrent.{Await, ExecutionContext, Future}
import java.util.concurrent.Executors
import scala.concurrent.ExecutionContext
Создаём отельный пул потоков, специально для нашего списка:
val pool = Executors.newFixedThreadPool(10)
val context = ExecutionContext.fromExecutor(pool)
Тут мы проходимся по всему списку с именами и запускаем их, не дожидаясь завершения:
val seqOfFutures: List[Future[Unit]] = list.map { name =>
Future { /* do something with name */ }(context)
}
Создаём ещё один Future который будет ждать весь список:
import scala.concurrent.ExecutionContext.Implicits.global
val sequenceFuture: Future[List[Unit]] = Future.sequence(seqOfFutures)
И именно этот один Future будем ждать мы:
Await.result(sequenceFuture, Duration.Inf)
pool.shutdown()