問題は、ワーカー スレッドの 1 つが「Hello future!」を実行する前にメイン スレッドが終了するスタンドアロン プログラムとして実行していることです。println
. (新しい futures ライブラリが生成するスレッドはデーモン スレッドです)。
Await
オブジェクト ( も) を使用して、フューチャが完了scala.concurrent
するまで待機することもできます。f
import scala.concurrent._
import scala.concurrent.util._
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
println("Test print after future")
Await.ready(f, Duration.Inf)
}
}
これは印刷できます:
Test print before future
Test print after future
Hello future!
または、「Hello future!」と出力することもできます。スレッドスケジュールに応じて、「テストプリント後」の前に。
同様に、次のようf
に、最後の前に が完了するまでメイン スレッドを強制的に待機させることができます。println
import scala.concurrent._
import scala.concurrent.util._
object Test {
def main(args: Array[String]) {
println("Test print before future")
val s = "Hello"
val f = future {s + " future!"}
f onSuccess {case v => println(v)}
Await.ready(f, Duration.Inf)
println("Test print after future")
}
}
どちらが印刷されますか:
Test print before future
Hello future!
Test print after future
ただし、 を使用するAwait
とブロックされることに注意してください。これはもちろん、メイン アプリケーション スレッドが終了しないことを確認するのに意味がありますが、通常、必要でない限り使用しないでください。
(Await
オブジェクトは、このような状況に必要なエスケープ ハッチですが、セマンティクスを考慮せずにアプリケーション コード全体で使用すると、実行が遅くなり、並列性が低下する可能性があります。たとえば、コールバックが指定された順序で実行されるようにする必要がある場合のandThen
やmap
メソッドなど、他の代替手段がありますFuture
。)