5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Futureをマスターする -おまけ-

Last updated at Posted at 2014-06-30

シリーズ目次

はじめに
コンパニオンオブジェクト操作
インスタンス操作
おまけ
Futureにハマる

おまけ

Future{ ... }と書けば、必ず新しいスレッドで処理が行われるのかと思っていたがそうではなく、実際は色々と複雑に制御されているようだ。
※Futureのソースコードを読んだわけではないので何故このような動きになるのかといった解説まではできていない。

object Main extends App {
  println("in main : " + Thread.currentThread().getId())

  val f1 = Future{ println(s"f1 : ${Thread.currentThread().getId()}"); 1 }
  val f2 = Future{ println(s"f2 : ${Thread.currentThread().getId()}"); 2 }

  val f = f1.flatMap { n1 =>
    println(s"f1#flatMap : ${Thread.currentThread().getId()}");

    f2.map{ n2 =>
      println(s"f2#map : ${Thread.currentThread().getId()}");
      n1 + n2
    }
  }

  f.onSuccess {
    case result => println(s"f#onSuccess : ${Thread.currentThread().getId()}")
  }

  Await.ready(f, Duration.Inf)
}

この実行結果は以下となる。
f1とf2は同一スレッドで実行されていることが確認できる。冒頭で述べたFuture{...}と書けば別スレッドで処理されると思っていたら違っていた、はこれを見たことによる。

main : 1296
f1 : 1290
f2 : 1290
f1#flatMap : 1297
f2#map : 1297
f#onSuccess : 1297

次に、f1とf2を以下のように変える。

  val f1 = Future{ Thread.sleep(3000); println(s"f1 : ${Thread.currentThread().getId()}"); 1 }
  val f2 = Future{ Thread.sleep(3000); println(s"f2 : ${Thread.currentThread().getId()}"); 2 }

結果は以下。
今度は別スレッドで実行されるようになった。

main : 1304
f1 : 1290
f1#flatMap : 1290
f2 : 1305
f2#map : 1290
f#onSuccess : 1290

次は更にonSuccessをforeachで書き換える。

  f.foreach {
    println(s"f#foreach : ${Thread.currentThread().getId()}")
    println(_)
  }

結果は以下。
なんとforeachのスレッド番号はMainと同じになった。それを裏付けるように出力順序も早くに出てくる。
もちろん結果は一番最後。
プログラマから見るとonSuccessと同じかもしれないが、実際は細かいレベルで振る舞いは異なるようだ。

main : 1313
f#foreach : 1313
f1 : 1306
f2 : 1314
f1#flatMap : 1306
f2#map : 1306
3

ほんの少しの変更だが今度は以下のように変えてみた。

  f.foreach { r =>
    println(s"f#foreach : ${Thread.currentThread().getId()}")
    println(r)
  }

結果は以下。
今度はforeachはMainとは別スレッドで呼ばれており、表示順も最後の方になった。
結果を変数に束縛するようにしたからなんだろう。

main : 1322
f1 : 1314
f1#flatMap : 1314
f2 : 1323
f2#map : 1314
f#foreach : 1314
3
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?