なんじゃくにっき

プログラミングの話題中心。

Scala de Design Pattern: Single Threaded Execution

 1つのスレッドからしか実行できないパターン。
Critical Sectionパターンとも。
  
 Javaではsynchronizedはキーワードだが、ScalaではAnyRefのメソッド。
なので、Scalaの場合、関数全体を同期化するには
関数の定義にsynchronized修飾子を付けることはできなくて、
関数の実体の先頭にsynchronizedを付ける。
  
 処理を別スレッドで実行させるには、scala.concurrent.ops.spawnを用いる。
 
以下、コード

例:


import scala.concurrent.ops._
import java.lang.Thread._

class synchronizedExample {
def hello(name: String) = synchronized (
for (i <- 1 to 7)
println(i + ": Hello, " + name)
)
}

object Main {
def main(args: Array[String]) = {
val example = new synchronizedExample
spawn(example.hello("hoge"))
spawn(example.hello("piyo"))
spawn(example.hello("huga"))
sleep(1000)
}
}

 
実行結果:

1: Hello, hoge
2: Hello, hoge
3: Hello, hoge
4: Hello, hoge
5: Hello, hoge
6: Hello, hoge
7: Hello, hoge
1: Hello, huga
2: Hello, huga
3: Hello, huga
4: Hello, huga
5: Hello, huga
6: Hello, huga
7: Hello, huga
1: Hello, piyo
2: Hello, piyo
3: Hello, piyo
4: Hello, piyo
5: Hello, piyo
6: Hello, piyo
7: Hello, piyo
 
synchronizedを付けない場合、実行順は保証されない。
↓synchronizedをつけなかった場合の例(毎回実行結果は異なる)

1: Hello, hoge
1: Hello, piyo
1: Hello, huga
2: Hello, huga
2: Hello, piyo
3: Hello, piyo
4: Hello, piyo
3: Hello, huga
4: Hello, huga
5: Hello, huga
6: Hello, huga
7: Hello, huga
2: Hello, hoge
5: Hello, piyo
6: Hello, piyo
7: Hello, piyo
3: Hello, hoge
4: Hello, hoge
5: Hello, hoge
6: Hello, hoge
7: Hello, hoge