Java言語で学ぶデザインパターン入門 マルチスレッド編
https://gyazo.com/6758c09b70f7e05aa92afe35de63eefb
長いこと買おう買おうと思いつつ、Kindle版が50%ポイント還元セールだったのを機にようやく購入。本当は『Java並行処理プログラミング』でマルチスレッド関連の勉強をし直したかったのだが、 Kindle 版が再販される気配もないため、同じく評判の高い結城先生著の本でマルチスレッドプログラミングに再入門することにした。以下、個人的な読書メモ。
Introduction1
逐次、並列、並行の違い
逐次(sequential)
複数の仕事を「順番に処理」
並列(parallel)
複数の仕事を「同時に処理」
並行(concurrent)
1つの仕事を「どんな順序で処理してもよい複数の作業」
CPUが1つなら並行処理は逐次処理となり、CPUが複数個あるなら並行処理を「並列的」に処理する、といったイメージ
英単語メモ
deposit (預金する)
預金する文脈では charge ではなくこちら
withdraw (引き出す)
あるオブジェクトのロック状態の調査方法
code:holdsLock
Thread.holdsLock(obj);
ウェイトセット
あるインスタンスの synchronized メソッド内で wait() を実行すると、当該スレッドは待合室(ウェイトセット)に入れられる
同一インスタンスの synchronized メソッド内でロックを獲得した別のスレッドが notify() or notifyAll() を実行すると、待合室(ウェイトセット)で待機しているスレッドが外に出される
外に出されたスレッドは wait() の次の処理へと進むことになる
ロックを持っていないスレッドが wait、notify、notifyAll を呼び出すと IllegalMonitorStateException がスローされる
syncronized なインスタンスメソッドと syncronized なクラスメソッドはロックが異なるため、複数スレッドから同時実行可能
code:instance lock
public void synchronized write() {
...
}
synchronized (this) {
...
}
code:class lock
public static void synchronized write() {
...
}
synchronized (Something.class) {
...
}
第1章 Single Threaded Execution
code:instance lock
synchronized (obj) {
...
}
誤ったインスタンスのロックを取るのは、自分の家を守ろうとして隣の家の鍵をかけるようなものです。p71
補講1
基本型・参照型の代入・参照はアトミックな操作である
ただし、longとdoubleの代入・参照はアトミックな操作ではない
実際にはアトミックな実装となっているかもしれないが、あくまでも処理系依存
longやdoubleをスレッド間で共有する場合には、synchronizedの中に入れるか、volatileとして宣言する
第2章 Immutable
補講2
CopyOnWriteArrayList
書き込み時に内部で確保している配列が丸ごとコピーされるため、要素が変更される心配がない
書き込み時の配列コピーに時間がかかるため、書く頻度が低く、読む頻度が圧倒的に高い局面で用いる
付録B Javaのメモリモデル
synchronizedやvolatileで正しく同期化しなければ、スレッドAがフィールドに書き込んだ値がすぐにスレッドBに見えるとは限らない
インスタンスはすべて共有メモリに確保される
共有メモリとは、いわゆるヒープメモリのこと
ローカル変数やメソッドの仮引数などは、共有メモリには確保されない
通常はスレッドが個々に持つスタックに確保されることになるが、実装依存であるため必ずしもそうなるとは限らない
つまり複数のスレッドからアクセスされることはない