Futureをマスターする -はじめに-

Futureについてちゃんと使いこなせるようになろうと思い立ち全操作ひと通りやってみることにした。
**※Scala 2.11.1のscaladocの全操作となります。**

trait Awaitable: 5
trait Future: 16
object Future: 10

# シリーズ目次
[はじめに](http://qiita.com/mtoyoshi/items/08766629abea6eb8e4bc)
[コンパニオンオブジェクト操作](http://qiita.com/mtoyoshi/items/297f6acdfe610440c719)
[インスタンス操作](http://qiita.com/mtoyoshi/items/f68beb17710c3819697f)
[おまけ](http://qiita.com/mtoyoshi/items/cc34d95bdffb6ce012e9)
[Futureにハマる](http://qiita.com/mtoyoshi/items/78912722f8ccc13d80f6) New!

# はじめに
全操作やっていく前に、最低限Futureの動きやFutureと組み合わせてよく使うものをはじめに確認しておく。

なお、以下の記事とても勉強になりましたので併せて読むと良いかも。リンクさせて頂きます。

- [Scala ExecutionContextって何 / Futureはスレッド立ち上げじゃないよ](http://mashi.hatenablog.com/entry/2014/11/24/010417)

## その１

```scala
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Main extends App {
  val msg = "hello"
  val f: Future[String] = Future {
    Thread.sleep(1000)
    msg * 5
  }

  println(f.isCompleted) // false
  val result1: Option[Try[String]] = f.value
  println(result1) // None

  Thread.sleep(2000)

  println(f.isCompleted) // true
  val result2: Option[Try[String]] = f.value
  println(result2.get.get) // hellohellohellohellohello
}
```

Future {}はFuture#applyであり、Futureインスタンスを生成する際の典型的なコードである。

なお、ネットでよく見るサンプルも[公式ドキュメント](http://docs.scala-lang.org/overviews/core/futures.html)もfuture{...}で生成しているものばかりなのですが、Scala2.11から[scala.concurrent](http://www.scala-lang.org/api/current/#scala.concurrent.package)のfutureメソッドはdeprecated扱いになっており、代わりにFutureを使うよう記述されています。
よって本記事ではfutre{ ... }は使用せずFuture{ ... }で統一しています。

これで、インスタンス生成と同時にMainとは別に並列実行が行われる。
isCompleteで並列実行側が終了したかどうかを確認できる。
valueで現時点の値を取得できる。終わっていなければNone、終わっていればSome[Try[T]]となる。

なお、このisCompletedやvalueはFutureではなく、mix-inされているAwaitableトレイトで宣言されたメソッドである。
Awaitableトレイトにはその他のメソッドとしてresult、ready、onCompleteがあるのだが、それらのメソッドを実行してみると、```Don't call `Awaitable` methods directly, use the `Await` object.```とこちらはコンパイルエラーになり強制的に呼び出せないようになっている。

## その２

```scala
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration

object Main extends App {
  val msg = "hello"
  val f: Future[String] = Future {
    Thread.sleep(1000)
    msg * 5
  }

  val result: String = Await.result(f, Duration.Inf)
  println(result) // hellohellohellohellohello
}
```

その１でコンパイルエラーメッセージにあったAwaitを使ったプログラム例である。
Main側でなんらかFutureの処理を待っておかないとMainスレッドが終了してしまうため、その１ではThread.sleepで待っていたわけだが当然こんなやり方は通常はせず、Awaitを使うことで特定のFutureインスタンスの処理を待つことができるようになる。

なお、Await#resultの問題点はFuture内で例外が起きるとこのメソッド実行時にも例外で返ってくる点であり、せっかくvalueの戻り値がTryになっているのにこの旨みを活かせてないように感じる。
こういうときはAwait#readyを使用する。Await#resultでは処理終了のタイミング調整&値取り出しの２つを行っているのに対し、readyは処理終了のタイミング調整だけを行う。よって値取り出しコードは自分で記述する。

```scala
Await.ready(f, Duration.Inf)
f.value.get match {
  case Success(msg) => println(msg)
  case Failure(ex) => println(ex.getMessage)
}
```

## その３

```scala
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.util.{ Try, Success, Failure }

object Main extends App {
  val msg = "hello"
  val f: Future[String] = Future {
    Thread.sleep(1000)
    msg * 2
  }
  f.onSuccess { case msg: String => println(msg) }
  f.onFailure { case t: Throwable => println(t.getMessage()) }

  Await.ready(f, Duration.Inf)
}
```

コールバック関数を登録するコード例。
成功時と失敗時の両方を記述するなら通常はonCompleteを使う。  

```scala
f.onComplete {
  case Success(msg) => println(msg)
  case Failure(t)   => println(t.getMessage())
}
```

※なおこれら終了時の処理を記述するonXxxコールバック関数はExecutionContextを必要とする（implicitに）。つまり別スレッドでの実行となる。
その３の例だと、Mainスレッド、Future.apply内部を実行するスレッド、Future#onXxxの終了時処理を実行するスレッドの計3スレッド（Future#applyおよび終了処理の実行はスレッドプール内の同じスレッドが充てられるかも、だが）が登場することとなる。
終了時の処理がMainスレッドではなく別スレッドで実行されるということを忘れていると、  [Futureにハマる](http://qiita.com/mtoyoshi/items/78912722f8ccc13d80f6) のような事になるので注意が必要。
少しフライングして言うと、map/flatMapなどFutureの値に対する操作処理は大抵ExecutionContextを必要とし、Mainとは別のスレッドで実行される（ことはもちろんのこと、for式等でflatMapやmapをチェーンさせた場合も、チェーンしたflatMapとmapに同じスレッドが充てられる保証はない。ExecutionContext.globalを使用している場合に内部でForkJoinPoolが採用されていると同じスレッドが充てられやすくはなりそう）ものがほとんどだ。  

# メソッドコンプリート状況
今回でカバーしたメソッド数は以下。

trait Awaitable: 5/5
trait Future: 3/16
object Future: 1/10