記事:Javaの理論と実践: JDK 5.0における、より柔軟でスケーラブルなロック
メモ:
- synchronized の特性
- 原子性(atomicity)と可視性(visibility)を提供
- 原子性:モニタオブジェクトに保護されたコードを実行できるのは一度に一つだけ
- 可視性:同じモニタオブジェクトで保護されたメモリは synchronized ブロックに入る前に必ずみえる
- volatile でも提供される
- 同期化の改善
- synchronized でブロックしている間にスレッドに割り込めない
- synchronized によるロック・アンロックは同じスタックフレームで行われる必要がある
- java.util.concurrent.lock
- ロックを抽象化
- 言語機能ではなく、クラスとして実装
- 異なったスケジューリングアルゴリズム、パフォーマンス特性、意味体系を持つ実装に変更可能
- ReentrantLock
- 条件変数(ConditionalVariable)
- Object クラスにはスレッド通信のための wait(), notify(), notifyAll() がある
- これらは高度でセンシティブな機能なので使わない方がいい。
- 例:wait(), notify() などをするには当該オブジェクトへのロックが必要
- Condition
- wait(), notify(), notifyAll() の代わりになる。
- await(), signal() signalAll() という名前になっている
- wait() などはオーバーライドできないため代用の名前を使っている
- フェアなロックとアンフェアなロック
- ロック取得とロック解放の順序が保証されるかどうか。
- フェア性を保証するとコストが高い
- 必要でない限りはアンフェアがおすすめ
- synchronized はフェアではない
- ReentrantLock が最強ではない
- ReentrantLock は高度な機能を持っている。普通は synchronized でよい。
- synchronized ではロックの解放忘れがありえない
- synchronized で保持しているロック情報はスレッドダンプに出せる
- synchronized なら多くの開発者が理解可能