Java Goldの試験対策として、そのままMkDocsに貼り付けられる形 式で、表の整理と「試験で合否を分ける+αの重要知識」をまと めました。
スレッドセーフ・コレクション徹底比較¶
Java Gold試験では、単に「スレッドセーフかどうか」だけでなく、**「どのような仕組みで安全性を担保しているか」**が問われます。
1. コレクション比較一覧表¶
| カテゴリ | 非スレッドセーフ | スレッドセーフ(全体ロック) | スレッドセーフ(高並列・モダン) |
|---|---|---|---|
| List | ArrayList |
Vector, Collections.synchronizedList() |
CopyOnWriteArrayList |
| Map | HashMap, TreeMap |
Hashtable, Collections.synchronizedMap() |
ConcurrentHashMap, ConcurrentSkipListMap |
| Set | HashSet, TreeSet |
Collections.synchronizedSet() |
CopyOnWriteArraySet, ConcurrentSkipListSet |
| Queue | ArrayDeque |
(なし) | ArrayBlockingQueue, LinkedBlockingQueue |
2. 【+α】試験に出る「仕組み」の深掘り¶
① CopyOnWriteArrayList の「スナップショット」¶
- 仕組み: 内部配列を変更する際、既存の配列をコピーして新しい配列を作成します。
- 試験の罠: イテレータ(Iterator)を作成した瞬間の配列(スナップショット)を参照し続けるため、反復処理中に元のリストを変更しても
ConcurrentModificationExceptionが発生しません。 - 用途: 参照が圧倒的に多く、変更が極稀な場合に適しています。
② ConcurrentHashMap の「分割ロック」¶
- 仕組み: Map全体をロックする
Hashtableと違い、内部をバケット(区画)に分け、**書き込む場所が違えば同時に更新できる**ように設計されています。 - 試験の罠:
nullをキーや値にすることは**許可されていません**(HashMapは OK)。 - 読み取り:
get()メソッドはロックをかけないため、非常に高速です。
③ SkipList 系(ConcurrentSkipListMap / Set)¶
- 特徴: 「スレッドセーフ」かつ「ソート済み(昇順)」 であることが最大の特徴です。
- 比較:
TreeMapのスレッドセーフ版だと考えると覚えやすいです。
④ BlockingQueue の「待機(ブロック)」¶
- put(e) / take(): キューが満杯なら待機、空なら待機。スレッド間でのデータの受け渡しに使用します。
- offer(e, time, unit): 指定時間だけ待って、ダメなら
falseを返して諦める。
3. 同期化ラッパー(Collections.synchronized...)の注意点¶
Collections.synchronizedList(new ArrayList<>()) などで生成したリストは、すべてのメソッドが同期化されますが、「複合操作」は安全ではありません。
Java
// 試験に出るパターン:反復処理は synchronized ブロックが必要
List<String> list = Collections.synchronizedList(new ArrayList<>());
synchronized(list) { // これを忘れると例外が発生する可能性がある
for (String s : list) {
System.out.println(s);
}
}
4. 試験対策サマリー(暗記ポイント)¶
- 例外の有無: 反復処理中に
removeやaddをして例外が出るのはArrayListや同期化ラッパー。出ないのはCopyOnWrite系。 - nullの許容:
ConcurrentHashMapやHashtableはnullNG。HashMapは OK。 - ソートの有無: 名前に
SkipListやTreeが入っていればソートされている。 - 計算量:
ConcurrentHashMapはハッシュテーブルなので 、SkipListは 。
次のステップ:学習の確認¶
この内容を MkDocs に反映させたあと、「ConcurrentHashMap で null を扱おうとしたらどうなるか?」 や 「CopyOnWriteArrayList のイテレータに最新の変更は反映されるか?」 といった観点でコードを 1 つ書いて実行してみると、記憶に定着しやすくなります。
Emacs 29.4 でのコード作成は順調ですか?もしビルドが完了していたら、実際に動かしてみましょう!