ハッシュセットスレッドは安全ですか?
スレッド セーフとは何ですか? データの読み取りと書き込みがスレッドから分離されている必要があり、データの損失や不整合が発生しないことを意味します。データが変更されるたびに上書きされるべきではありません。
銀行引き出しの典型的な例を考えてみましょう。アカウント A は最初は 0、スレッド A は 0 を読み取り、その後 100 を保存します (データはまだ書き込まれません)。スレッド B は 0 を読み取り、100 も保存します。 time 最後に表示されるアカウントの残高は 100 です。これは非科学的であり、スレッドアンセーフと呼ばれます。したがって、入出金のオブジェクトを制御し、操作するオブジェクトにデータロックをかけて、データを更新した後、他のスレッドがスレッドセーフを実現できるようにする必要があります。
今回は HashSet を証明します。Set インターフェースが実装されていることはわかっています。 Set の特徴は、保存されたデータが繰り返されないことです。なぜなら、まず内部に保存されているデータを読み込んで存在するかどうかを確認し、存在する場合は保存されず、存在しない場合は保存されます。つまり、データの保存操作は、最初に読み取り、次に書き込みという 2 つのステップに分割されます。スレッドセーフではないと仮定すると、スレッド A が設定されたオブジェクトに要素がないと判断し、要素を挿入しようとしているときに、スレッド B もオブジェクトに要素がないと判断し、挿入されないという状況が考えられます。最終的には、2 つの同一の要素が挿入されます。
デモは次のように設計します:
class TestHashSet implements Runnable{ // 实现Runnable 让该集合能被多个线程访问 Set<Integer> set = new HashSet<Integer>(); // 线程的执行就是插入5000个整数 @Override public void run() { for (int i = 0;i < 5000;i ++) { set.add(i); } } }
メイン スレッドでテストします:
TestHashSet run2 = new TestHashSet(); // 实例化两个线程 Thread t6 = new Thread(run2); Thread t7 = new Thread(run2); // 启动两个线程 t6.start(); t7.start(); // 当前线程等待加入到调用线程后 t6.join(); t7.join(); // 打印出集合的size System.out.println(run2.set.size());
出力される結果のほとんどは予想どおり 5000 ですが、場合によっては 5000 が表示されることがあります。 5000 を超える状況。これにより、前述の状況が発生し、HashSet がスレッドセーフなクラスではないことが証明されます。
実際、ソース コードを見ると、HashMap は HashSet の内部でデータを維持するために使用されていることがわかりました。その根本的な理由は、HashMap がスレッドセーフなクラスではないことです。これは、HashSet の非スレッド安全性につながります。 Java コレクション クラスの詳細については、[PHP 中国語 Web サイト: java ビデオ ]
最後に、完全なコード ケースの検証:
import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** * 验证HashSet不是线程安全 */ public class HashSetTest { public static void main(String[] args) { final Set<Integer> set = new HashSet<>();// 结果可能大于1000 // final Set<Integer> set = Collections.synchronizedSet(new HashSet<>());// 结果等于1000 // final Set<Integer> set = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());// 结果等于1000 // 往set写入1-1000 Runnable runnable = new Runnable() { @Override public void run() { for (int i = 1; i <= 1000; i++) { set.add(i); } } }; int threadNum = 10;// 线程数 List<Thread> threadList = new ArrayList<>(); for (int i = 0; i < threadNum; i++) { Thread thread = new Thread(runnable); threadList.add(thread); thread.start(); } // 主线程等待子线程执行完成 for (Thread thread : threadList) { try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(set.size());// 结果可能大于1000 } }
以上がハッシュセットスレッドは安全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

指定した要素をコレクションから削除するには、Java で HashSet.remove() メソッドを使用します。 HashSet は Set インターフェイスを実装したコレクション クラスであり、重複した要素の格納は許可されず、要素の順序も保証されません。 HashSet を操作する場合、remove() メソッドを使用してセット内の要素を削除できます。 HashSet のremove() メソッドには 2 つのオーバーロード形式があります。 booleanremove(Objectobj): 指定されたオブジェクトをコレクションから削除します。

Java の HashSet 関数は、ハッシュ テーブルに基づいて実装されたコレクション クラスです。コレクションクラスなので当然コレクション操作の機能を持っていますが、今回はHashSet関数を使ってコレクション操作を行う方法を紹介します。 1. HashSet の定義と宣言 HashSet はコレクションクラスなので、最初に Java.util パッケージをインポートする必要があります。 importjava.util.HashSet; 次に、HashSet インスタンスを作成できます。

Java ドキュメントの解釈: HashSet クラスの contains() メソッドの使用法の詳細な説明。HashSet クラスは、Java で一般的に使用されるコレクション クラスの 1 つです。Set インターフェイスを実装し、ハッシュ テーブル データ構造に基づいています。効率的な挿入、削除、検索操作を実現します。このうち、contains() メソッドは、HashSet クラスが提供する重要なメソッドで、セットに指定された要素が含まれているかどうかを判断するために使用されます。この記事では、HashSet クラスの contains() メソッドの使用法を詳細に分析します。

HashSet クラスの addAll() メソッドを使用して、コレクション内のすべての要素を別のコレクションに追加します。HashSet は、Java コレクション フレームワークの実装クラスです。AbstractSet を継承し、Set インターフェイスを実装します。 HashSet はハッシュ テーブルに基づく順序なしのセットであり、要素の重複は許可されません。これには、コレクション内の要素を操作するためによく使用されるメソッドが多数用意されており、その 1 つが addAll() メソッドです。 addAll() メソッドの機能は、指定されたものを追加することです。

Java の HashSet.add() メソッドを使用してコレクションに要素を追加するのは非常に簡単なので、以下で詳しく紹介します。 HashSet は Java のコレクション クラスです。AbstractSet クラスを継承し、Set インターフェイスを実装します。HashSet の特性は、順序付けされておらず、繰り返しがなく、基礎となる実装はハッシュ テーブルに基づいています。 HashSet.add() メソッドを使用して要素を追加する場合は、次の点に注意する必要があります。 HashSet はオブジェクト型の要素のみを格納できます。

コレクションを別のコレクションに追加するには、HashSet クラスの addAll() メソッドを使用します。HashSet は Java のコレクション クラスです。Set インターフェイスを実装し、ハッシュ テーブルに基づいて実装されます。 HashSet コレクションでは重複要素は許可されず、コレクション内の要素は順序付けされていません。開発では、多くの場合、あるコレクションから別のコレクションに要素を追加する必要があります。 HashSet クラスは、この関数を簡単に実装するための addAll() メソッドを提供します。以下で説明します。

HashSet のクラス図 HashSet の簡単な説明 1. HashSet は Set インターフェイスを実装します 2. HashSet の最下層は実際には HashMap によって実装されます publicHashSet(){map=newHashMap();} 3. Null を格納できますが、null は 1 つだけです4.HashSetは要素の順序を保証しません(つまり、要素が格納される順序と要素が取り出される順序が同じであることは保証されません)。インデックスの結果は決定されます。 5. 重複した要素は存在できない HashSet の基礎となるメカニズムは、HashSet の最下層が HashMap、HashMap の最下層が HashMap であることを説明しています。配列 + リンク リスト + 赤黒ツリー シミュレーションの構造です。配列 + リンクされたリスト /*

HashSet クラスの保持All() メソッドを使用して、2 つのコレクションの共通部分を取得します。HashSet は、一意のオブジェクトのセットを格納するために使用される Java のコレクション クラスです。 restartAll() メソッドは、HashSet クラスによって提供されるメソッドで、2 つの HashSet の共通部分を取得するために使用されます。 Java では、コレクションは複数のオブジェクトを格納するために使用できる一般的に使用されるデータ構造です。 HashSet は、コレクション クラスで一般的に使用される具体的な実装であり、ハッシュ テーブルを通じてオブジェクトを格納および取得します。