『Javaの理論と実践: アトミックで行く』を読んで

記事:Javaの理論と実践: アトミックで行く

メモ:

  • JDK 5.0 でアトミック変数が追加された
    • wait-free, lock-free なアルゴリズムが利用可能になった
    • 以前は native code を使う必要があった
  • スレッドの協調
    • マルチスレッド環境ではスレッド間の協調が必要
    • ロック(synchronized など)による協調
      • 競合があると高い。競合がない場合には今の JVM では安い。
    • volatile 変数
      • read-modify-write をアトミックにできない
  • 協調の粒度
    • モニタを使ったロックは粒度が荒い。
    • モダンなプロセッサーは細かい粒度の協調機構を持っている
      • ハードウェア同期プリミティブ
  • ハードウェア同期プリミティブ: Compare and Swap (CAS) 命令
    • Intel, SPARC, POWER などで compare-and-swap と呼ばれる命令をサポートしている
      • 当初は単一ビットのみだった
    • メモリ位置(V)、期待される古い値(A)、新しい値(B)というオペランド
    • 「メモリ位置 V は値 A を持っているはずで、持っていたら B をいれる。そうでなかったら変更しないで、現在の値を読む」
      • 値が変更されていないことを確信して、メモリ操作ができる
  • Lock-Free と Wait-Free
    • Wait-Free
      • 他のスレッドの動向に関わらず、必ず有限回で操作が終了する
    • Lock-Free
      • 一部のスレッドのみが継続して進行する。一部のスレッドは進行しないかもしれない
      • 例えば CAS でリトライを永遠にしているかも、、、
    • この分野は昔からよく研究されていて、実装が複雑だがパフォーマンス上の利点が大きい。
  • java.util.concurrent.atomic
    • 当該プラットフォームで利用できる最速のネイティブ機構を利用
      • CAS
      • load liked/store conditional
      • Spin Lock
  • ABA 問題
    • CAS では、A => B => A と変わっていると変更が検知できない。
    • これに対して、バージョン番号を記録する対応策がある
      • AtomicStampedReference クラスとして利用可能。
  • パフォーマンス
    • Atomic 変数で実装した乱数実装のパフォーマンスは ReentrantLock よりもいい
    • JVM の改良による恩恵

感想

Wait-Free と Lock-Free にはなんだかややこしい定義があるみたい。あんまり深く追わなかった。