私はExecutionContextのスレッド数を制御したかったのです。だから私はThreadPoolExecutorのインスタンスを作成し、そこからExecutionContextを作成しました。scala.concurrent.Future.on異なるExecutorServiceで実行時間を待つ
そして私はいくつかの未来を作成し、それらにOnSuccessコールバックを添付しました。私は、未来の仕事が終わるたびに、それぞれのonSuccessコールバックが呼び出されることを期待していました。しかし、すべてのonSuccessコールバックが同時に実行されたことがわかりました。
import java.util.concurrent.{ Executors, ForkJoinPool }
import scala.concurrent.{ Await, ExecutionContext, Future }
import scala.concurrent.duration.Duration
object Main extends App {
implicit val ec = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(2))
// implicit val ec = ExecutionContext.fromExecutorService(new ForkJoinPool(2))
val start = System.currentTimeMillis()
val futures = for {
i <- 1 to 10
} yield Future[Int] {
Thread.sleep(i * 1000)
i
}
futures.foreach { f =>
f.onSuccess { case i =>
println(s"${i} Success. ${System.currentTimeMillis() - start}ms elapsed.")
}
}
Await.ready(Future.sequence(futures.toList), Duration.Inf)
ec.shutdown()
}
// ThreadPoolExecutor Result
// 1 Success. 25060ms elapsed.
// 2 Success. 25064ms elapsed.
// 3 Success. 25064ms elapsed.
// 4 Success. 25064ms elapsed.
// 5 Success. 25064ms elapsed.
// 6 Success. 25064ms elapsed.
// 7 Success. 25065ms elapsed.
// 8 Success. 25065ms elapsed.
// 9 Success. 25065ms elapsed.
// 10 Success. 30063ms elapsed.
// ForkJoinPool Result
// 1 Success. 1039ms elapsed.
// 2 Success. 2036ms elapsed.
// 3 Success. 4047ms elapsed.
// 4 Success. 6041ms elapsed.
// 5 Success. 12042ms elapsed.
// 6 Success. 12043ms elapsed.
// 7 Success. 25060ms elapsed.
// 8 Success. 25060ms elapsed.
// 9 Success. 25060ms elapsed.
// 10 Success. 30050ms elapsed.
上記の結果は、それぞれ同時に印刷されたものではありません。しかし、ThreadPoolExecutorの代わりにForkJoinPoolを使用すると、この問題は緩和されます。私はExecutionContextとFutureを悪用しましたか?
編集:スレッドの数が未来の数より少ないと問題が発生することがわかりました。上記のコードを編集して問題を再現し、実行時間を印刷しました。
私は私が最終的に将来のコールバック(onCompleteのか、するonSuccess)を設けのExecutionContextのスレッドで実行されていることを知っていた
実行するコードを正確に記入する必要があります。あなたが貼り付けたものは不完全であり、あなたが描写した出力を生成しません。実際、私のために、あなたが見ているものではなく、あなたが期待しているとおりにすべてが機能します。 – Haspemulator
私はちょうど質問を編集しました。問題は、スレッドの数が未来よりも少ない場合に発生します。 – jyshin
各Futureを「blocking」とマークする必要がありますか?[this StackOverflow post](http://stackoverflow.com/questions/19681389/) scala-concurrent-blockingの使用)? – Castaglia