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