マップ同期集合とマップ目次

同期集合とマップ

スレッドセーフな可変なマップが欲しい場合、SynchronizedMapトレイトを希望する特定のマップ実装にミックスインできます。 例えば以下のコードに示すようにSynchronizedMapHashMapにミックスインできます。 この例はまずMapおよびSynchronizedMapの2つのトレイトと1つのクラスHashMapscala.collection.mutableパッケージからインポートするところから始まります。 この例の残りの部分はシングルトンオブジェクトMapMakerの定義であり、 1つのメソッドmakeMapを定義します。 makeMapメソッドは文字列のキーから文字列の値への可変なマップを返り値の型として宣言します。

  import scala.collection.mutable.{Map,
      SynchronizedMapHashMap}
  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?"
        }
    }
  }
SynchronizedMapをミックスインする。

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を検討すると良いでしょう。

!!!同期マップについて説明する!!!

続いては: 不変なコレクションの具象クラス


マップ同期集合とマップ目次