この記事は主に、さまざまな Java コレクションのスレッド セーフ性を詳細に紹介するもので、編集者はそれが非常に優れていると考えたので、必要な友人の参考のためにここで共有します。
スレッドの安全性
まず第一に、JVM にはメイン メモリがあり、スレッドが変数を操作する場合、各スレッドには独自の作業メモリが必要であることを理解する必要があります。独自のメモリ内で動作し、作業用
メモリにコピーを作成し、操作の完了後にメイン
メモリに書き込みます。複数のスレッドが同じ変数を同時に操作すると、予期しない結果が発生する可能性があります。上記の説明に基づいて、対応するシナリオを思いつくのは簡単です。
同期を使用するための鍵は、変更する変数またはメソッドなどの適切だと思われる他のオブジェクトをモニターを作成し、各スレッドがこれを取得するようにロックすることです。ロックすると、取得したロックが解放される前に、作業メモリへのロード -> use&assign -> メインメモリへのストアのプロセスが実行されます。これにより、いわゆるスレッドセーフが実現されます。
スレッド セーフとは何ですか? スレッド セーフはどのように達成されるのですか (原理)? スレッド セーフとは、不確実な結果を生成せずに複数のスレッドが同じコードにアクセスすることを意味します。スレッドセーフなコードを作成すると、スレッドの同期が低下します。
Java 関連のコレクション
Vector、ArrayList、LinkedList
Vector と ArrayList はどちらも、可変数のオブジェクト アプリケーションのセットを表すために使用でき、アクセスできます。要素がランダムに含まれます。
Vector のメソッドはすべて同期されており (Synchronized)、スレッドセーフですが、ArrayList のメソッドはそうではありません。スレッドの同期は必然的にパフォーマンスに影響するため、ArrayList のパフォーマンスは Vector よりも優れています。
ArrayList と LinkedList の違い
データ項目のリストを処理するために、Java は ArrayList と LinkedList という 2 つのクラスを提供します。ArrayList の内部実装は内部配列 Object[] に基づいているため、概念的にはは配列に似ていますが、LinkedList の内部実装は接続されたレコードのセットに基づいているため、リンクされたリスト構造に似ており、パフォーマンスに大きな違いがあります。
上記の分析から、ArrayList の前または途中にデータを挿入する場合は、それに応じて後ろのすべてのデータを移動する必要があり、そのため、操作が の列に対して行われる場合、確実に時間がかかることがわかります。 data データを先頭や中間ではなく最後に追加し、要素にランダムにアクセスする必要がある場合、ArrayList を使用するとパフォーマンスが向上します
そして、リンクされたリスト内の要素にアクセスするときは、要素の一方の端から開始する必要があります途中でリンクされたリスト。必要な要素が見つかるまで、接続方向に要素ごとに検索します。したがって、データ列の前または途中でデータを追加または削除する操作を行う場合は、要素に順番にアクセスします。 、 LinkedList を使用する必要があります。
プログラミングにおいて、1と2の2つの状況が交互に現れる場合は、特定の実装を気にせずに、Listのような一般的なインターフェイスを使用することを検討できます。特定の状況では、そのパフォーマンスは特定の実装によって決まります。
HashTable、HashMap、HashSet
HashTable と HashMap は同じストレージメカニズムを使用し、その実装は基本的に同じです。違いは次のとおりです:
1)、HashMap は非スレッドセーフであり、HashTable はスレッドセーフです。スレッドセーフであるため、内部メソッドは基本的に同期されます。
2)、HashTable は null 値の存在を許可しません。
HashTableのputメソッドを呼び出す際、キーがnullの場合は直接NullPointerExceptionがスローされます。他にも、初期化された Entry 配列のサイズなど、微妙な違いがありますが、基本的な考え方は HashMap と同じです。
HashSet:
1. HashSet は HashMap に基づいて実装されており、容量制限はありません。
2. HashSet はスレッドセーフではありません。
3. HashSet は順序を保証しません。
HashMap:
1. HashMap は、配列を使用して、キーと値で構成される Entry オブジェクトを容量制限なしで保存します。
2. HashMap は、キー ハッシュに基づいて Entry オブジェクトが配列内で格納されている場所を検索し、リンク リストを使用してハッシュの競合を解決します。
3. HashMap は、要素を挿入するときに配列の容量を拡張する必要がある場合があります。容量を拡張する場合、ハッシュを再計算し、オブジェクトを新しい配列にコピーする必要があります。
4. HashMap はスレッドセーフではありません。
5. HashMap トラバーサルは Iterator を使用します
HashTable
1。
2. HashTable の Key も Value も null にすることはできません。
3. HashTable のトラバーサルは列挙を使用します。
TreeSet,TreeMap
TreeSet:
1. TreeSet は TreeMap に基づいて実装され、並べ替えをサポートします。
2. TreeSet はスレッドセーフではありません。
HashSet と TreeSet の説明から、TreeSet は HashSet と同様に完全に Map に基づいて実装されており、どちらも指定された位置の要素を取得するための get(int) をサポートしていません (取得するにはトラバースする必要があります)。いくつかの並べ替えのサポート。たとえば、Comparator 実装、decendingSet、decendingIterator などを渡します。
TreeMap:
1. TreeMap は赤黒ツリーに基づく典型的な Map 実装であるため、Comparator 実装を渡すか、Comparable インターフェイスを実装するキー オブジェクトを渡す Key 比較メソッドが必要です。
2. TreeMap はスレッドセーフではありません。
概要
以上がJava のさまざまなコレクションのスレッド セーフティ分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。