3

私はこの方法を書きました:

import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

Future.sequence が List[Future] を Future[List] に収集し、すべての先物 (私の場合は f1 と f2) が完了するのを待ってから、Future[List] seq で onSuccess を呼び出すことを期待していました。

しかし、このコードを何度も実行すると、「List(1, 2)」がたまにしか出力されず、期待どおりに動作しない理由がわかりません。

4

2 に答える 2

5

これを一度試して、

import scala.concurrent._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  implicit val exec = ExecutionContext.fromExecutor(Executors.newCachedThreadPool)
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

これは常に印刷されますList(1,2)。理由は簡単です。exec上記はスレッドの ExecutionContext (デーモン スレッドではない) であり、例のように、 ExecutionContext はExecutionContext.Implicits.globalデーモン スレッドを含む暗黙的に取得されたデフォルトのものです。

seqしたがって、プロセスはデーモンであるため、 future が完了するのを待たずに終了します。完了した場合seqは、印刷されます。しかし、それはいつも起こるわけではありません

于 2015-01-22T10:44:41.757 に答える
2

future が完了する前に、アプリケーションが終了しています。

未来が完了するまでブロックする必要があります。これは、ExecutionContext の変更、新しい ThreadPool、Thread.sleep などのインスタンス化、またはメソッドの使用など、さまざまな方法で実現できます。scala.concurrent.Await

コードの最も簡単な方法は、 を使用することAwait.readyです。futureこれは、指定された時間ブロックします。以下の変更されたコードでは、アプリケーションは終了する前に 5 秒間待機します。

scala.concurrent.duration待機時間を指定できるように、追加のインポートにも注意してください。

import scala.concurrent._
import scala.concurrent.duration._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }

  Await.ready(seq, 5 seconds)
}

代わりに を使用すると、結果のリストが返されるため、メソッドAwait.resultをスキップすることもできます。onSuccess

例:

val seq: List[Int] = Await.result(Future.sequence(lf), 5 seconds)
println(seq)
于 2015-01-23T09:18:11.977 に答える