『Javaの理論と実践: Javaメモリ・モデルを修正する 第2回』を読んで

記事: Javaの理論と実践: Javaメモリ・モデルを修正する 第2回

メモ:

  • 可視性の問題
    • すぐに他のスレッドの変更が見えるとは限らない
    • これを保証するのがメモリモデル
      • volatile, synchronized, final のメモリセマンティクスを決定している
  • 同期化ブロックと可視性
    • スレッドが同期化ブロックを出る時は、ローカルキャッシュをはき出す
    • スレッドが同期化ブロックに入る時は、ローカルキャッシュを無効化
  • volatile に対する新たな保証
    • 旧:volatile 変数への操作のみ順序を保証していた
    • 新:「スレッド A が volatile 変数 V に書き込み、スレッド B が V から読み出す時、V に書き込む時に A から見えるどんな変数値も、Bから見えることが保証される」
    • 旧モデルよりもアクセスコストが高くなったが、意味体系がより有用になった(番兵としての利用が可能になった)
  • 事前発生 (happens-before)
    • 特定の操作の部分配関係を保証するための、happens-before という関係を非公式に定義
  • データ・レース(Data races)
    • ある変数を複数のスレッドの読み書きが happens-before 関係によって配列されていない場合、Data race が発生する
  • 古いメモリモデルでは double-checking lock を解決しない
    • volatile 以外はリオーダーされて可視性が保証されない
    • 新しいメモリモデルは、double-checking lock を解決するが、volatile アクセスが高くなってるから、double-checking lock は使わない方がよい
    • Initialize on demand holder を使うべき
      • クラス初期化の一部としての操作は、すべてのスレッドから可視である
  • final フィールドはコンストラクト後、可視性が保証される
  • まとめ
    • volatile のセマンティクスが強化された。ただし、コストは増加した。
    • final field のセマンティクスが強化された。不変オブジェクトの実用性が高くなった。

感想

同じことが何回も書かれているのだが、こうやって繰り返し学習することで、どんどん知識が定着している気がする。