HashMapスレッドは安全ですか?
Javaで最も一般的に使用されるMapコレクションはHashMapです。これはスレッドセーフではありません。
次の2つのシナリオを見てください。
1.メソッド内のローカル変数で使用される場合、ローカル変数は現在のスレッドレベルの変数に属し、他のスレッドはその変数にアクセスできないため、現時点ではスレッドの安全性と不安定性の問題はありません。
2.シングルトンオブジェクトメンバー変数で使用する場合 現時点では、複数のスレッドが同じHashMapにアクセスするようになり、同じHashMapで操作するとスレッドの安全性に問題があります。
スレッドセーフなマップ
シナリオ2でのスレッドセーフの問題を回避するために、HashMapをメンバー変数として使用することはできません。スレッドセーフマップを使用するようにしてください。スレッドセーフマップとは何ですか?
1、ハッシュテーブル
プライベートMap <String、Object> map = new Hashtable <>();
HashTableのソースコードを見てみましょう
HashTableのget / putメソッドはすべて、synchronizedキーワードによって変更され、メソッドレベルでブロックされ、共有リソースロックを占有するため、1つのスレッドだけがgetまたはputを同時に実行でき、同時にget / put操作を実行できないため、これはこの種の同期されたコレクションは非常に非効率的であり、通常、このコレクションを使用することは推奨されません。
2、SynchronizedMap
private Map <String、Object> map = Collections.synchronizedMap(new HashMap <String、Object>());
これは、ツールクラスのメソッドを直接使用してSynchronizedMapを作成し、受信したHashMapオブジェクトをラップして同期をパッケージ化するために、そのソースコードを見てみましょう。
この同期方法の実装も比較的単純です。SynchronizedMapの実装方法はオブジェクトロックを追加することです。HashMapの各操作は、最初にこのミューテックスのオブジェクトロックを取得して入力する必要があるため、パフォーマンスはHashTableよりも高くなりません。そして、お勧めできません。
3. ConcurrentHashMap推奨
プライベートMap <String、Object> map = new ConcurrentHashMap <>();
これは最も推奨されるスレッドセーフマップでもあり、最も複雑な実装でもあります。バージョンごとに実装が異なります。jdk8以前は、セグメント化されたロックを使用し、毎回16バケットに分割されていましたバケットの1つだけがロックされ、赤と黒のツリーとCASアルゴリズムがjdk8に追加されてそれを実現します。
実装は非常に複雑ですが、使用方法も非常に簡単です。Javaインタビューで質問する頻度も非常に高いです。最も重要なことは、パフォーマンスが上記の2つの同期方法よりもはるかに高速であることです。使用することをお勧めします。
私はブログを読んで詳細を読むことをお勧めします:
1. Java JVM、コレクション、マルチスレッド、新機能シリーズのチュートリアル
2. Spring MVC、Spring Boot、Spring Cloudシリーズのチュートリアル
3. Maven、Git、Eclipse、Intellij IDEAシリーズのツールチュートリアル
4. Java、バックエンド、アーキテクチャ、Alibabaおよびその他の主要メーカーに対する最新のインタビューの質問
気分が良い、それを好き+転送することを忘れないでください!