『Javaの理論と実践: スレッド・セーフの特性について』を読んで

スレッド・セーフの特性について

記事: https://www.ibm.com/developerworks/jp/java/library/j-jtp09263/

メモ:

  • スレッドセーフは「all or nothing」の命題ではない
  • クラスの保証するスレッドセーフ性を厳密に文書化するべきである
    • インスタンスメソッド呼び出しに対して、当該インスタンスを同期化するだけで「スレッドセーフ」だと勘違いする開発者がいる
    • 例:SimpleDateFormat はスレッドセーフではないがドキュメント化されていなくて、みんな間違った
  • スレッドセーフの定義
    • 複数のスレッドから安全に(safety)に呼び出せるならスレッドセーフである」 => 定義の循環がある
    • クラスごとの仕様に影響されるので循環するのはしょうがない
  • クラスはシングルスレッドでも精確に振る舞う必要がある
    • 精確な振る舞い:不変条件・必須条件・事後条件を満たさない状態にはなりえない
    • ただし、public なメソッド経由で観察できる状態が対象である
  • スレッドセーフは「複数スレッドからアクセスされても精確な振る舞いをする」こと
  • スレッドセーフの程度
    • all or nothing ではない
    • Bloch が5カテゴリに分けた(厳密な分類は不可能。あくまで参考の一つ)
    • 外部での追加同期が必要かに注目
  • 1: 不変
    • 不変オブジェクトは常にスレッドセーフ
    • 追加同期無し
  • 2: スレッドセーフ
    • 複数のスレッドから追加同期なしで制約条件を満たし、オブジェクトが変な状態にならないこと
  • 3: 条件付きスレッドセーフ  - 個々のオペレーションはスレッドセーフだが、一定のシーケンスは外部同期がいる
  • 4: スレッド互換
    • スレッドセーフではないが、外部で適切に同期化すると並行環境でも問題がない場合
  • 5: 反スレッド
    • static なデータを同期無しで変更する場合
    • 例:System.setOut など。

感想

この5分類は Effective Java でもカバーされてるな。そこまでいってないが、、、