Scala为Seq每个元素调用返回Future的慢函数无法正常执行问题
问题根因
加Thread.sleep后slowFunction无输出的核心原因是JVM主线程提前终止:
Scala默认全局执行上下文创建的线程均为守护线程,主线程执行完毕后JVM会直接终止所有守护线程,不会等待未完成的异步任务。去掉Thread.sleep时slowFunction执行速度快,能赶在主线程退出前完成,因此可以看到完整输出。
在代码末尾添加Await.result(results, Duration.Inf)阻塞主线程等待异步任务执行完成,即可看到加Thread.sleep后的完整输出。
串行执行实现方案
不需要借助Timer实现间隔调用,直接通过Future链式拼接即可实现前一个任务执行完成后再启动下一个任务的逻辑,同时保证每个任务至少执行一次、降低系统负载,参考实现如下:
import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Await import scala.concurrent.duration.Duration val inputsFromDb = Future { Seq(1, 2, 3) } def slowFunction(input: Int): Future[Boolean] = { Future { Thread.sleep(1000) println(s"Returning from slow function for input $input") true } } val results: Future[Boolean] = inputsFromDb.flatMap { inputs => // foldLeft按顺序拼接Future,实现串行执行 inputs.foldLeft(Future.successful(true)) { (prevTask, input) => for { _ <- prevTask _ = println(s"Calling slow function for input $input") res <- slowFunction(input) } yield res } } // 阻塞主线程等待所有任务执行完成 Await.result(results, Duration.Inf)
运行后输出为严格串行的结果:
Calling slow function for input 1 Returning from slow function for input 1 Calling slow function for input 2 Returning from slow function for input 2 Calling slow function for input 3 Returning from slow function for input 3
内容的提问来源于stack exchange,提问作者pradhyo
相关产品推荐
相关产品推荐

