简短的回答
的ExecutionContext.Implicits.global
创建守护线程。 (请参阅Scala源代码scala.concurrent.impl.ExecutionContextImpl.DefaultThreadFactory
)这些是JVM在退出时不会等待的线程(在您的情况下,主例程停止时)。因此,在作为守护程序线程运行的userNameFuture
完成之前,主例程已经完成,并且不会等待以便未来的线程完成。
为防止发生这种情况,可以使用非守护线程(例如,创建这样的隐式ExecutionContext
implicit val ec = (scala.concurrent.ExecutionContext.fromExecutorService(Executors.newCachedThreadPool()))
,或者使用
Await.result(userNameFuture, Duration.Inf)
在主程序
。
注意:如果使用后一种方法与都Await.result
和onSuccess
回调,但仍可能发生,首先主程序退出,没有用户名的输出将被制成,因为没有订单,其中首先发生。
龙答案
看一看代码
object F2 {
def main(args: Array[String]): Unit = {
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Success
val userFuture = Future {
Thread.sleep(1000)
println("userFuture runs on: " + Thread.currentThread().getName)
Thread.sleep(1000)
User("Me")
}
val userNameFuture: Future[String] = userFuture map {
user => {
Thread.sleep(2000)
println("map runs on: " + Thread.currentThread().getName)
Thread.sleep(2000)
user.name
}
}
val p = Promise[Boolean]()
userNameFuture onSuccess {
case userName => {
println("onSuccess runs on : " + Thread.currentThread().getName)
println(s"user's name = $userName")
p.complete(Success(true))
}
}
println("main runs on: " + Thread.currentThread().getName)
println("main is waiting (for promise to complete) .... ")
Await.result(p.future, Duration.Inf)
println("main got promise fulfilled")
println("main end ")
}
}
其输出
main runs on: run-main-b
main is waiting (for promise to complete) ....
userFuture runs on: ForkJoinPool-1-worker-5
map runs on: ForkJoinPool-1-worker-5
onSuccess runs on : ForkJoinPool-1-worker-5
user's name = Me
main got promise fulfilled
main end
首先,你可以看到,这两个userFuture并作为ForkJoinPool
它的地图操作运行守护进程线程。
二,主要通过首先运行,打印“主要等待承诺”并在此等待(仅用于消除目的)以实现承诺。如果主要不会在这里等待(尝试自己,通过评论出Await
)承诺完成,主例程将只打印其他两行并完成。其结果是,在JVM将关闭(你永远不会看到的onComplete
输出),通过SBT
绝招(调试)
在一般情况下,如果你正在使用SBT,并通过run
调用程序的执行,然后你仍然可以看到守护进程线程的输出,因为如果从SBT内部启动,JVM不会终止。 因此,如果通过SBT run
启动,则很快会返回到SBT提示符(因为主例程已完成),但在SBT中可以看到线程的输出(onComplete
)。
http://stackoverflow.com/questions/31900681/the-future-is-not-complete –
如果你删除了'应用程序'它按预期工作。 – Jus12