同期集合とマップ | 目次 |
スレッドセーフな可変なマップが欲しい場合、SynchronizedMapトレイトを希望する特定のマップ実装にミックスインできます。 例えば以下のコードに示すようにSynchronizedMapをHashMapにミックスインできます。 この例はまずMapおよびSynchronizedMapの2つのトレイトと1つのクラスHashMapをscala.collection.mutableパッケージからインポートするところから始まります。 この例の残りの部分はシングルトンオブジェクトMapMakerの定義であり、 1つのメソッドmakeMapを定義します。 makeMapメソッドは文字列のキーから文字列の値への可変なマップを返り値の型として宣言します。
import scala.collection.mutable.{Map,
SynchronizedMap, HashMap}
object MapMaker {
def makeMap: Map[String, String] = {
new HashMap[String, String] with
SynchronizedMap[String, String] {
override def default(key: String) =
"Why do you want to know?"
}
}
}
makeMapの本体の最初の文ではSynchronizedMapをミックスインする新しいHashMapを構築します:
new HashMap[String, String] with
SynchronizedMap[String, String]
このコードが与えられると、ScalaのコンパイラはSynchronizedMapをミックスインしたHashMapの合成サブクラスを作成し、そのインスタンスを作成し(て返し)ます。 この合成クラスは以下のコードにより、defaultという名前のメソッドも上書きします:
override def default(key: String) =
"Why do you want to know?"
もしマップに対して特定のキーに対する値を得ようとして、そのキーに対する関連付けを備えてない場合はデフォルトではNoSuchElementExceptionが得られます。 しかし、もし新しいマップクラスを定義し、defaultメソッドを上書きすると、存在しないキーについて問い合わされた場合、新しいマップはdefaultの返り値を返します。 よって、以前の同期マップのコードからコンパイラによって生成された、HashMapの合成子クラスは、存在しないキーで問い合わされた場合ちょっとそっけない文字列"Why do you want to know?"を返します。
makeMapメソッドが返す可変なマップはSynchronizedMapトレイトをミックスインしているため、マップは複数のスレッドから一度にアクセスできます。 マップへの各アクセスは同期されます。 これはマップがインタプリタで1つのスレッドから使われる例です:
scala> val capital = MapMaker.makeMap
capital: scala.collection.mutable.Map[String,String] = Map()
scala> capital ++ List("US" -> "Washington",
"Paris" -> "France", "Japan" -> "Tokyo")
res0: scala.collection.mutable.Map[String,String] =
Map(Paris -> France, US -> Washington, Japan -> Tokyo)
scala> capital("Japan")
res1: String = Tokyo
scala> capital("New Zealand")
res2: String = Why do you want to know?
scala> capital += ("New Zealand" -> "Wellington")
scala> capital("New Zealand")
res3: String = Wellington
同期マップを作ったときと同様に同期集合も作成できます。 例えばこのようにSynchronizedSetをミックスインすると同期HashSetを作成できます:
import scala.collection.mutable
val synchroSet =
new mutable.HashSet[Int] with
mutable.SynchronizedSet[Int]
最後に、同期コレクションについて検討している場合は代わりに同期コレクションjava.util.concurrentを検討すると良いでしょう。
続いては: 不変なコレクションの具象クラス
同期集合とマップ | 目次 |