なんじゃくにっき

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

Scala de Design Pattern: Read Write Lock

 リソースのReadとReadは衝突しないが、
Read-Write, Write-Writeは衝突する、というパターン。
synchronizedをReadとWriteに付けるだけではRead-Readの衝突を回避できないので、
別にロックを管理するオブジェクトを用いる。
  
 Javajava.util.concurrent.locks.ReadWriteLockというその名の通りのinterfaceがあるので、
ずぼらしてそれを使って済ませる。
 
下のurlの内容を参考にした。 
http://www.itarchitect.jp/technology_and_programming/-/33321-5.html
 

import java.util.concurrent.locks._
import java.lang.Thread._
import scala.actors._
import scala.util.Random

class Resource {
val lock = new ReentrantReadWriteLock(true)
val random = new Random

def read(name: String) = {
lock.readLock.lock()
println(name + ": readロック獲得")
try {
// ここに読み取り処理を書く
sleep((random.nextFloat * 1000.0).toInt)
} finally {
println(name + ": readロック開放")
lock.readLock.unlock()
}
}

def write(name: String) = {
lock.writeLock.lock()
println(name + ": writeロック獲得")
try {
// ここに書き込み処理を書く
sleep((random.nextFloat * 1000.0).toInt)
} finally {
println(name + ": writeロック開放")
lock.writeLock.unlock()
}
}
}

class Reader(name: String, resource: Resource) extends Actor {
def act() {
for (i <- 0 to 2)
resource.read(name)
}
}

class Writer(name: String, resource: Resource) extends Actor {
def act() {
for (i <- 0 to 2)
resource.write(name)
}
}

object Main {
def main(args: Array[String]) = {
val resource = new Resource

for (i <- 0 to 2) {
new Reader("Reader " + i, resource).start()
new Writer("Writer " + i, resource).start()
}

sleep(10000)
}
}

  
実行結果:

Writer 0: writeロック獲得
Writer 0: writeロック開放
Reader 0: readロック獲得
Reader 1: readロック獲得
Reader 1: readロック開放
Reader 0: readロック開放
Writer 1: writeロック獲得
Writer 1: writeロック開放
Writer 0: writeロック獲得
Writer 0: writeロック開放
Reader 1: readロック獲得
Reader 0: readロック獲得
Reader 0: readロック開放
Reader 1: readロック開放
Writer 1: writeロック獲得
Writer 1: writeロック開放
Writer 0: writeロック獲得
Writer 0: writeロック開放
Reader 0: readロック獲得
Reader 1: readロック獲得
Reader 1: readロック開放
Reader 0: readロック開放
Writer 1: writeロック獲得
Writer 1: writeロック開放
Reader 2: readロック獲得
Reader 2: readロック開放
Writer 2: writeロック獲得
Writer 2: writeロック開放
Reader 2: readロック獲得
Reader 2: readロック開放
Writer 2: writeロック獲得
Writer 2: writeロック開放
Reader 2: readロック獲得
Reader 2: readロック開放
Writer 2: writeロック獲得
Writer 2: writeロック開放
read-readは複数ロックを獲得できるが、
read-write, write-writeはConflict。