簡短的回答
的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