spawnで処理を並列実行する
scala.concurrent.opsで定義されているspawnメソッドを使って、任意の処理を別スレッドで並列に実行させることができます。
- 処理は引数で渡します。
- 内部的には、処理を実行するだけの専用のスレッドが1つ生成されるようです。スレッドは処理の実行完了後に終了します。
import scala.concurrent.ops._ // scala.concurrent.opsのメソッドをstatic インポート。 import java.lang.Thread._ object SpawnSample { def main(args: Array[String]) { // 指定した処理を並列に実行する。 def proc(name:String) = 0 to 3 foreach( i=> println( name + " : meow!" )) spawn( proc( "mii" ) ) spawn( proc( "tora" ) ) spawn( proc( "shiro" ) ) sleep(1000) // ほんとはちゃんと待たないといけない。 } }
実行結果です。
mii : meow! tora : meow! shiro : meow! mii : meow! tora : meow! shiro : meow! mii : meow! tora : meow! shiro : meow! mii : meow! tora : meow! shiro : meow!
Erlangぽいなー。(→並列処理(プロセスの開始とプロセス間通信まで))ところで、内部的に起動しているスレッドを得る手段がないので、処理の完了の待ち合わせやinterruptができない・・・。(待ち合わせはfuture使うとできるけど。)戻り値でスレッドを返してくれてもいいんじゃないかとちょっと思った。
futureで処理の完了を待ち合わせる
scala.concurrent.opsには、futureという関数も定義されており、こっちを使うと処理の完了の待ち合わせと結果の取得ができるようになります。
import scala.concurrent.ops._ import java.lang.Thread._ object FutureSample { def main(args: Array[String]) { // 処理。5秒スリープした後、5を返す。 def logic = { println( "start." ) sleep( 5 ) 5 } // 非同期で処理を実行する。 // 戻り値で結果を受け取るための関数が返される。 // これを評価すると、非同期処理の実行結果が返される。 // このとき、非同期処理が実行中であれば、処理の完了まで待たされる。 var a = future( logic ) var b = future( logic ) // わかりやすいように。 println( "start wait." ) // a, bの結果を待つ。 println( a() + b() ) } }
実行結果です。
start. start. start wait. 10