Scala での将来のシーケンス
この記事では、Scala の futures
について学びます。
Scala では、Future
は、現在は使用できない可能性がありますが、将来使用できるようになる値です。
Scala でタスクを並行/並列に実行したい場合は、Futures
を使用します。 ネイティブ Java thread
を使用することもできますが、Scala Future
の方がはるかに簡単に記述できるため、推奨されます。
簡単に言えば、Future
は、アルゴリズム/アプリケーションを同時に実行する簡単な方法を提供します。 フューチャが作成されると、同時に実行が開始され、ある時点で結果が得られ、最終的にはある時点で結果が得られます。
Futures
を Scala で順次実行する
futures
が順次実行を開始すると、それは順次実行です。 スレッドプールを管理する ExecutionContext
をインポートする必要があります。 それがなければ未来
は動きません。
よりよく理解するために例を見てみましょう。
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Example extends App {
def task(n: Int) = Future
{
Thread.sleep(1000)
println(n) //to observe the output
n + 1
}
//running in a sequential way
val temp = for {
t1 <- task(1)
t2 <- task(t1)
t3 <- task(t2)
t4 <- task(t3)
t5 <- task(t4)
} yield List(t1,t2,t3,t4,t5)
temp.map(x => println(s"Completed. ${x.size} tasks were executed"))
Thread.sleep(5000) //so that the main thread doesn't quit quickly
}
コードを実行すると、5つのタスクが順番に次々と実行されることがわかります。
Scala での Future の同時/並列実行
コード例:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Example extends App {
def task(n: Int) = Future
{
Thread.sleep(1000)
println(n) //to observe the output
n + 1
}
val temp = for {
t1 <- task(1)
t2 <- Future.sequence(List(task(t1), task(t1)))
t3 <- task(t2.head)
t4 <- Future.sequence(List(task(t3), task(t3)))
t5 <- task(t4.head)
} yield t2.size + t4.size
temp.foreach(x => println(s"Done. $x task run in concurrent manner"))
Thread.sleep(6000) // needed to prevent the main thread from quitting
// too early
}
上記のコードでは、Future.sequence
を使用しました。これは、先物のリスト
を受け取り、それらを リストの未来
に変換します。 同時に実行したいすべてのタスク/ジョブをリストとして渡す必要があります。
出力:
上記のコードを実行すると、t2
と t4
が並行して実行されることがわかります。 並列処理を行う際に覚えておくべきことの 1つは、スレッドの可用性に依存するため、実行が常に並列であるとは限らないということです。
少数のスレッドのみが存在する場合、少数のジョブのみが並行して実行され、他のジョブはスレッドが解放されるのを待ちます。
まとめ
このチュートリアルでは、Futures
とは何か、プログラムを同時に作成および実行する際にどのように役立つかを理解しました。