我正在玩scala Futures,默认全局背景和我自己的ExecutionContext
。
我很好奇global context
在所有执行后如何关闭。因为如果我创建自己的ExecutionContext
,我必须手动关闭。
示例,
1)使用全局executionContext,
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
object ParallelTasksWithGlobalExecutionContext {
private val data: Iterable[Input] = Iterable("data1", "data2", "data3")
def main(args: Array[String]): Unit = {
val f: Future[Unit] = Future.traverse(data) { d =>
println(s"[${Thread.currentThread().getName}]-Firing $d")
processData(d)
} map { processed =>
processed.foreach(p => println(s"""[${Thread.currentThread().getName}]-$p"""))
}
Await.result(f, Duration.Inf)
}
type Input = String
type Output = String
def processData: (Input => Future[Output]) = data => {
Future {
Thread.sleep(5000)
s"[Thread-${Thread.currentThread().getName}] data $data is processed."
}
}
}
输出
$ sbt "runMain ParallelTasksWithGlobalExecutionContext"
[info] Running ParallelTasksWithGlobalExecutionContext
[run-main-0]-Firing data1
[run-main-0]-Firing data2
[run-main-0]-Firing data3
[scala-execution-context-global-59]-[Thread-scala-execution-context-global-58] data data1 is processed.
[scala-execution-context-global-59]-[Thread-scala-execution-context-global-59] data data2 is processed.
[scala-execution-context-global-59]-[Thread-scala-execution-context-global-60] data data3 is processed.
[success] Total time: 6 s, completed Apr 1, 2018 12:44:36 AM
执行完成后,应用程序终止。
2)使用自己的ExecutionContext - 在完成所有执行后,应用程序不会终止,直到我手动.shutdown
。
import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService, Future}
import scala.util.{Failure, Success}
object ParallelTasksWithCustomExecutionContext {
private val data: Iterable[Input] = Iterable("data1", "data2", "data3")
implicit val singleThreadContext: ExecutionContextExecutorService = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(3))
def main(args: Array[String]): Unit = {
Future.traverse(data) { d =>
println(s"[${Thread.currentThread().getName}]-Firing $d")
processData(d)
} onComplete {
case Success(processed) =>
processed.foreach(p => println(s"""[${Thread.currentThread().getName}]-$p"""))
//singleThreadContext.shutdown()
case Failure(f) =>
f.printStackTrace()
//singleThreadContext.shutdown()
}
}
type Input = String
type Output = String
def processData: (Input => Future[Output]) = data => {
Future {
Thread.sleep(5000)
s"[Thread-${Thread.currentThread().getName}] data $data is processed."
}
}
}
输出
$ sbt "runMain ParallelTasksWithCustomExecutionContext"
[info] Running ParallelTasksWithCustomExecutionContext
[run-main-0]-Firing data1
[run-main-0]-Firing data2
[run-main-0]-Firing data3
[pool-7-thread-1]-[Thread-pool-7-thread-1] data data1 is processed.
[pool-7-thread-1]-[Thread-pool-7-thread-2] data data2 is processed.
[pool-7-thread-1]-[Thread-pool-7-thread-3] data data3 is processed.
<hangs>
这是JVisualVM线程监视器,
我的问题是scala的全局上下文如何在不询问客户端的情况下自动终止?
答案 0 :(得分:1)
Scala global
上下文是使用Thread
工厂创建的,它生成Threads
守护进程,因此一旦所有用户线程完成了它们,它们(线程)将不会阻止JVM退出执行。
检查ExecutionContextImpl
方法def createDefaultExecutorService(reporter: Throwable => Unit): ExecutorService
。