Scala 2.10 で Future を使用します。これらは、Scala チーム、Akka チーム、および Twitter 間の共同作業であり、フレームワーク全体で使用するためのより標準化された将来の API と実装に到達しました。ガイドを公開しました: http://docs.scala-lang.org/overviews/core/futures.html
Scala 2.10 の Future には、完全にノンブロッキング (デフォルトではマネージド ブロッキング操作を実行する機能が用意されています) であり、構成可能であるだけでなく、タスクを実行するための暗黙的なスレッド プールと、タイムアウトを管理するためのユーティリティが付属しています。
import scala.concurrent.{future, blocking, Future, Await, ExecutionContext.Implicits.global}
import scala.concurrent.duration._
// Retrieve URLs from somewhere
val urls: List[String] = ...
// Download image (blocking operation)
val imagesFuts: List[Future[...]] = urls.map {
url => future { blocking { download url } }
}
// Do something (display) when complete
val futImages: Future[List[...]] = Future.sequence(imagesFuts)
Await.result(futImages, 10 seconds).foreach(display)
上記では、最初にいくつかのものをインポートします。
future
: 未来を作るためのAPI。
blocking
: マネージド ブロッキングの API。
Future
: Future のコレクションのための便利なメソッドを多数含む Future コンパニオン オブジェクト。
Await
: Future でのブロックに使用されるシングルトン オブジェクト (その結果を現在のスレッドに転送する)。
ExecutionContext.Implicits.global
: デフォルトのグローバル スレッド プール、ForkJoin プール。
duration._
: タイムアウトの期間を管理するためのユーティリティ。
imagesFuts
あなたが最初に行ったものとほとんど同じままです-ここでの唯一の違いは、マネージドブロッキングを使用することです- blocking
. 渡されたコードのブロックに実行時間の長い操作またはブロックしている操作が含まれていることをスレッド プールに通知します。これにより、プールは新しいワーカーを一時的に生成して、すべてのワーカーがブロックされることが決して起こらないようにすることができます。これは、ブロッキング アプリケーションでの枯渇 (スレッド プールのロックアップ) を防ぐために行われます。スレッド プールは、マネージド ブロッキング ブロック内のコードがいつ完了するかを認識しているため、その時点で予備のワーカー スレッドを削除します。つまり、プールは予想されるサイズに縮小されます。
(追加のスレッドが作成されるのを絶対に防ぎたい場合は、Java の NIO ライブラリなどの AsyncIO ライブラリを使用する必要があります。)
次に、Future コンパニオン オブジェクトのコレクション メソッドを使用して、imagesFuts
から に変換List[Future[...]]
しFuture[List[...]]
ます。
Await
オブジェクトはdisplay
、呼び出し元のスレッドで実行されることを保証する方法です。Await.result
つまり、渡されたフューチャーが完了するまで、現在のスレッドを強制的に待機させるだけです。(これは内部的にマネージド ブロッキングを使用します。)