スレッドの同時実行制御(synchronized)
synchronizedで複数スレッドの同時実行制御ができます。
- 機能はJavaのsynchronizedと同じで、指定された処理が、1スレッドからのみ実行されるようになります。同時に複数スレッドから実行されることはありません。
- Javaと違って、すべての参照型の基底クラスであるAnyRefのメソッドとして定義されています。
- 引数で同期化する処理を受け取ります。
- また、受け取った処理の結果を値として返します。
import scala.concurrent._ import scala.concurrent.ops._ import java.lang.Thread._ object SynchronizeSample { def main(args: Array[String]) { // 同期化用オブジェクト val monitor = new Object // 並列実行する処理 // monitor.synchronizedにより、複数スレッドで並列に実行されることはない。 def proc(name:String) = monitor.synchronized( 0 to 3 foreach( i=> println( name + " : meow!" )) ) // 3スレッドで並列実行 spawn( proc( "mii" ) ) spawn( proc( "tora" ) ) spawn( proc( "shiro" ) ) sleep(1000) // ほんとはちゃんと待たないといけない。 } }
実行結果です。
mii : meow! mii : meow! mii : meow! mii : meow! tora : meow! tora : meow! tora : meow! tora : meow! shiro : meow! shiro : meow! shiro : meow! shiro : meow!
同時実行制御してない場合の動作は昨日のサンプルを参照。
Lockを使う
同時実行制御はscala.concurrent.Lockを使ってもできます。こっちは次のような感じで使います。
import scala.concurrent._ import scala.concurrent.ops._ import java.lang.Thread._ object LockSample { def main(args: Array[String]) { // 同期化用オブジェクト val lock = new Lock // 並列実行する処理 // Lockにより、複数スレッドで並列に実行されることはない。 def proc(name:String) = { try { lock.acquire // ロックを確保 0 to 3 foreach( i=> println( name + " : meow!" )) } finally { lock.release // ロックを解放 } } // 3スレッドで並列実行 spawn( proc( "mii" ) ) spawn( proc( "tora" ) ) spawn( proc( "shiro" ) ) sleep(1000) // ほんとはちゃんと待たないといけない。 } }