並列に実行されない書き方
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
val start = System.currentTimeMillis
for{
_ <- Future(Thread.sleep(3000))
_ <- Future(Thread.sleep(3000))
} yield println("the process time is " + (System.currentTimeMillis - start) + " msec.")
// the process time is 6141 msec.
並列に実行される書き方
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
val start = System.currentTimeMillis
val a = Future(Thread.sleep(3000))
for{
_ <- Future(Thread.sleep(3000))
_ <- a
} yield println("the process time is " + (System.currentTimeMillis - start) + " msec.")
// the process time is 3195 msec.
解説
for式の中では、Futureを使っていても前から順番に、前の処理が終わってから次の行に進む。前の処理結果を次の行で使うかもしれないから。なので「並列に実行されない書き方」がそうなるのは、そりゃそうだ。
「並列に実行される書き方」は、 val a = Future(Thread.sleep(3000))
の行に来た時点でFutureの中の処理が始まり、Futureなので中の処理終了を待たずに次の行に進む。それからfor式の中では最初の_ <- Future(Thread.sleep(3000))
が終わってから_ <- a
に来るわけだけれど、a
に代入した時点で処理はスタートしてるので_ <- a
では処理結果を取り出すだけ、という感じになる。
あとがき
書いてみると簡単な話だけど、最近までここらへんの理解が曖昧だった。あんまりこういうこと書いてくれてる資料ってなかったんですよね、あったら教えて下さい。