以下是我同时运行任务的课程。我的问题是,即使在获得所有功能的结果后,我的应用程序也永远不会结束。我怀疑线程池没有关闭,这导致我的应用程序即使在我的任务之后还活着。请告诉我,我用谷歌搜索了很多但没有运气。我在这里缺少什么?
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.collection.mutable.ListBuffer
import scala.util.Failure
import scala.util.Success
object AppLauncher{
def launchAll(): ListBuffer[Future[String]] = {
// My code logic where I launch all my threads say 50
null
}
def main(args:Array[String]):Unit= {
register(launchAll())
}
def register(futureList: ListBuffer[Future[String]]): Unit =
{
futureList.foreach { future =>
{
future.onComplete {
case Success(successResult) => {
println(successResult)
}
case Failure(failureResult) => { println(failureResult) }
}
}
}
}
}
答案 0 :(得分:0)
通常情况下,当您使用Future
的可迭代时,您应该使用Future.sequence
更改,例如Seq[Future[T]]
到Future[Seq[T]]
。
所以,使用类似的东西:
def register(futureList: Seq[Future[String]]) = Future.sequence(futureList) foreach { results =>
println("received result")
}
如果您想要在完成后映射每个未来并打印输出,您也可以执行以下操作;
def register(futureList: Seq[Future[String]]) = Future.sequence (
futureList.map(f => f.map { v =>
println(s"$v is complete")
v
}) ) map { vs =>
println("all values done $vs")
vs
}
答案 1 :(得分:-1)
最后我能够找出问题。问题是因为线程池即使在我的期货成功完成后也没有终止。我尝试通过稍微改变我的实现来隔离问题。
// import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.collection.mutable.ListBuffer
import scala.util.Failure
import scala.util.Success
//Added ExecutionContex explicitly
import java.util.concurrent.Executors
import concurrent.ExecutionContext
object AppLauncher {
//Implemented EC explicitly
private val pool = Executors.newFixedThreadPool(1000)
private implicit val executionContext = ExecutionContext.fromExecutorService(pool)
def launchAll(): ListBuffer[Future[String]] = {
// My code logic where I launch all my threads say 50
null
}
def main(args: Array[String]): Unit = {
register(launchAll())
}
def register(futureList: ListBuffer[Future[String]]): Unit =
{
futureList.foreach { future =>
{
println("Waiting...")
val result = Await.result(future, scala.concurrent.duration.Duration.Inf)
println(result)
}
}
pool.shutdownNow() executionContext.shutdownNow()
println(pool.isTerminated() + " Pool terminated")
println(pool.isShutdown() + " Pool shutdown")
println(executionContext.isTerminated() + " executionContext terminated")
println(executionContext.isShutdown() + " executionContext shutdown")
}
}
将突出显示的代码添加到关闭池之前的结果
false池终止
true Pool shutdown
false executionContext终止
true executionContext shutdown
添加突出显示的代码后解决了我的问题。我确保我的代码中没有资源泄漏。我的场景允许我在所有期货完成时杀死池。我知道我将优雅的回调实现改为阻塞实现,但它仍然解决了我的问题。