好吧,讓我們從秒示例開始。 考慮下面的代碼片段:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
object Test2{
def main(args:Array[String]):Unit={
val f = Future{Thread.sleep(5000); "i'm done"}
val r = for{
_ <- f
} yield "completed"
println(r)
}
}
猜猜它會打印?它打印
Future(<not completed>)
Process finished with exit code 0
所以其實這裏你是不是等待將來完成時,您只需映射第一未來的結果,並返回它作爲其他未來的第一個完成後,將完成。正如你所看到的,該計劃不會等到最終的未來完成並正好退出。 for
對期貨的理解是用於映射和平滑映射它們的糖語法。
該Await.result
和Await.ready
真的等待未來完成(或超時通過)。但是它們是以阻塞的方式實現的,所以你使用這些方法的線程將被阻塞。這並不總是很糟糕,有時可能會有所幫助。例如。在小測試程序或REPL會話中,您最終將未來計算的結果輸出到控制檯,或者例如在無論如何需要等待結果並且在等待測試時無需執行測試的情況下。
另一種看到你導致這樣的小程序的方法是使用scala.io.StdIn.readLine()
,這樣主線程就會掛起而不會退出。考慮其中說明了這以下,也爲您提供了一個更多附加的方式來等待將來完成:
object Test2{
def main(args:Array[String]):Unit={
val f = Future{Thread.sleep(5000); "i'm done"}
f foreach (println(_))
scala.io.StdIn.readLine()
}
}
運行它,你會看到該程序不會退出,打印的未來和退出的結果,那麼只有在您按下ENTER鍵後。
foreach
應用於未來是添加onComplete
偵聽器的快捷方式。非常方便的一個。
至於如果未來完成while
循環不斷地檢查 - 我認爲這可能是等待,因爲它會繼續在主線程忙,浪費更多的空閒CPU電源不是依靠高效地實現Await.result
最糟糕的方式。阻礙其他事情也可能是高效率和低效率的。
爲了理解所有這些有未來的東西,你需要清楚地認識到,未來的實際執行不會發生在你發起它的同一個線程中。在我們所有的例子中,我們只是在主線程中定義了未來,然後在導入的執行上下文中的一個線程中執行了它。
理想情況下,你應該避免等待(儘可能地推出)和連鎖期貨(如在'for'理解中那樣)。 – Thilo
如果你想在while循環中輪詢,它應該是'while(!isCompleted)'。但最好使用'Await.ready',這是爲了這個確切的目的而製作的。 – Thilo
hwan下面有兩個貌似好的答案,他們有什麼好處? – halfer