リソースのReadとReadは衝突しないが、
Read-Write, Write-Writeは衝突する、というパターン。
synchronizedをReadとWriteに付けるだけではRead-Readの衝突を回避できないので、
別にロックを管理するオブジェクトを用いる。
Javaにjava.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.Randomclass 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 Resourcefor (i <- 0 to 2) {
new Reader("Reader " + i, resource).start()
new Writer("Writer " + i, resource).start()
}
sleep(10000)
}
}
実行結果:
read-readは複数ロックを獲得できるが、
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-write, write-writeはConflict。