Java ConcurrentHashMap完全マスター:操作、実例、ベストプラクティス
Java ConcurrentHashMap
JavaのConcurrentHashMapクラスを探り、その作成と操作方法を学び、実践的なコード例で主要な利点を発見してください。
JavaコレクションフレームワークのConcurrentHashMapクラスは、スレッドセーフなマップ実装を提供します。複数スレッドが同時に読み書きしても、マップの整合性を損ないません。
ConcurrentMapインターフェースを実装し、java.util.concurrentの一部です。
ConcurrentHashMapの作成
まずクラスをインポートします:
import java.util.concurrent.ConcurrentHashMap;
その後インスタンス化。初期容量と負荷係数を指定するか、デフォルトに任せます。
// 容量8、負荷係数0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
パラメータ
capacity- 初期バケット数(例では8)loadFactor- マップが60%満杯でリサイズトリガー
デフォルトコンストラクタは容量16、負荷係数0.75のマップを作成:
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
既存マップからConcurrentHashMapを作成
他のマップのエントリで新しいConcurrentHashMapを初期化できます。
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> evenNumbers = new HashMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
System.out.println("HashMap: " + evenNumbers);
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers);
numbers.put("Three", 3);
System.out.println("ConcurrentHashMap: " + numbers);
}
}
出力
HashMap: {Four=4, Two=2}
ConcurrentHashMap: {Four=4, Two=2, Three=3}
ConcurrentHashMapの主要メソッド
要素の挿入
put(K key, V value)- マッピングを追加または置換putAll(Map<? extends K, ? extends V> m)- 一括挿入putIfAbsent(K key, V value)- キーが存在しない場合のみ挿入
ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
evenNumbers.putIfAbsent("Six", 6);
System.out.println("偶数: " + evenNumbers);
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.putAll(evenNumbers);
System.out.println("数値: " + numbers);
出力
偶数: {Six=6, Four=4, Two=2}
数値: {Six=6, One=1, Four=4, Two=2}
要素へのアクセス
ビューコレクションやキー/値取得メソッドを使用します。
entrySet()、keySet()、values()- エントリ、キー、値のコレクションを返すget(K key)- 値を取得。存在しない場合はnullgetOrDefault(K key, V defaultValue)- 値または指定デフォルトを取得
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("Map: " + numbers);
System.out.println("Entries: " + numbers.entrySet());
System.out.println("Keys: " + numbers.keySet());
System.out.println("Values: " + numbers.values());
int val = numbers.get("Three");
System.out.println("get(\"Three\"): " + val);
int def = numbers.getOrDefault("Five", 5);
System.out.println("getOrDefault(\"Five\", 5): " + def);
出力
Map: {One=1, Two=2, Three=3}
Entries: [One=1, Two=2, Three=3]
Keys: [One, Two, Three]
Values: [1, 2, 3]
get("Three"): 3
getOrDefault("Five", 5): 5
エントリの削除
remove(K key)- マッピングを削除して値を返すremove(K key, V value)- 現在値が一致する場合のみ削除。booleanを返す
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
int removed = numbers.remove("Two");
System.out.println("削除された値: " + removed);
boolean deleted = numbers.remove("Three", 3);
System.out.println("{Three=3}エントリ削除? " + deleted);
System.out.println("更新後のマップ: " + numbers);
出力
削除された値: 2
{Three=3}エントリ削除? true
更新後のマップ: {One=1}
一括操作
これらのメソッドは並列処理を活用し、大きなマップを効率的に処理します。
forEach()
エントリをイテレーションし、オプションで並列実行し、コンシューマーを適用します。
numbers.forEach(4, (k, v) -> System.out.println("key: " + k + " value: " + v));
// トランスフォーマー付き:
numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
ここで4は並列閾値です。マップが4要素以上なら並行実行される可能性があります。
search()
述語を満たすエントリを検索。最初の一致を返します。
String key = numbers.search(4, (k, v) -> v == 3 ? k : null);
System.out.println("検索されたキー: " + key);
reduce()
リデューサーで値を集約。合計、積、カスタム蓄積に有用。
int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
System.out.println("値の合計: " + sum);
ConcurrentHashMap vs HashMap
- スレッドセーフティ -
ConcurrentHashMapは安全な並行変更を許可。HashMapは非スレッドセーフ - 一括メソッド -
ConcurrentHashMapはforEach、search、reduceで並列処理を提供
なぜConcurrentHashMapを使うのか?
- 最小限のブロッキングで高並行性をサポート
putIfAbsentなどの操作で誤った上書きを防止- 組み込み同期により外部ロックが不要
内部的に16セグメントに分割され、最大16スレッドが異なるセグメントを同時に変更可能
Java
- Java演算子をマスター:種類、構文、実践例
- Javaコメント:種類、使い方、ベストプラクティス
- Java拡張forループをマスター:構文、例、ベストプラクティス
- Java文字列をマスター:生成、メソッド、ベストプラクティス
- Javaインターフェース完全ガイド:概念、実装、ベストプラクティス
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaのtry-with-resourcesをマスターする:自動リソース管理の仕組みと活用法
- Javaアノテーション完全ガイド:種類、配置場所、実践例
- Javaアサーション完全ガイド:バグ早期発見とコード信頼性の向上
- Javaコレクションアルゴリズム完全ガイド:ソート、シャッフル、検索など
- Java 乱数生成:Random クラスと Math.random 実践ガイド