スレッド セーフとは何ですか? データの読み取りと書き込みがスレッドから分離されている必要があり、データの損失や不整合が発生しないことを意味します。データが変更されるたびに上書きされるべきではありません。
銀行引き出しの典型的な例を考えてみましょう。アカウント 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衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

Dreamweaver Mac版
ビジュアル Web 開発ツール

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

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

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

ホットトピック









