hashset线程安全吗?
什么是线程安全,就是对于数据的读写要线程隔离,不能导致数据的丢失和不一致,每次修改数据都不应该被覆盖掉。
还是举银行取款的经典例子,账户A起初为0,线程A读出0,然后存100(还没写入数据),线程B读出为0,也存100,这个时候最后的账户我们看到的是余额100。这是不科学的,这就叫线程不安全。所以我们要控制存取款的对象,让我们操作数据的对象加锁,更新完数据,其他的线程才能,达到线程安全。
这次我们来证明HashSet,我们知道实现了Set接口。Set的特点就是存放的数据不会重复。因为它的内部会首先读内部保存的数据,是否存在,如果存在就不存放进去,否则存放进去。也就是说数据的存入操作是分两步,首先读取,然后写入。假设不是线程安全,那很可能出现的一种情形就是当线程A判断该set对象没有某个元素,正准备将该元素插入之前,线程B也判断该对象不存在该元素,也准备插入,最后的结果导致了两个相同的元素被插入了。
我们这样来设计demo:
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的情况。这就出现了之前提到的情况,证明了HashSet不是线程安全的类。
其实查看源代码发现HashSet内部维护数据的采用的是HashMap,根本原因是HashMap不是线程安全的类。导致了HashSet的非线程安全。更多java集合类的知识请关注【PHP中文网: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 } }
Atas ialah kandungan terperinci hashset线程安全吗?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Gunakan kaedah HashSet.remove() dalam Java untuk mengalih keluar elemen tertentu daripada koleksi. HashSet ialah kelas koleksi yang melaksanakan antara muka Set Ia tidak membenarkan penyimpanan elemen pendua dan tidak menjamin susunan elemen. Apabila mengendalikan HashSet, anda boleh menggunakan kaedah remove() untuk memadamkan elemen dalam set. Kaedah remove() HashSet mempunyai dua bentuk terlebih beban: booleanremove(Objectobj): mengalih keluar objek yang ditentukan daripada koleksi

Fungsi HashSet dalam Java ialah kelas koleksi yang dilaksanakan berdasarkan jadual cincang. Memandangkan ia adalah kelas koleksi, ia secara semula jadi mempunyai fungsi operasi pengumpulan Artikel ini akan memperkenalkan cara menggunakan fungsi HashSet untuk melaksanakan operasi pengumpulan. 1. Definisi dan pengisytiharan HashSet HashSet ialah kelas koleksi, jadi anda perlu mengimport pakej Java.util terlebih dahulu. importjava.util.HashSet Kemudian anda boleh mencipta contoh HashSet: HashSet<

Tafsiran dokumentasi Java: Penjelasan terperinci tentang penggunaan kaedah contains() kelas HashSet ialah salah satu kelas koleksi yang biasa digunakan dalam Java Ia melaksanakan antara muka Set dan berdasarkan struktur data jadual cincang. dengan operasi sisipan, pemadaman dan carian yang cekap. Antaranya, kaedah contains() ialah kaedah penting yang disediakan oleh kelas HashSet, yang digunakan untuk menentukan sama ada set mengandungi elemen yang ditentukan. Artikel ini akan menganalisis secara terperinci penggunaan kaedah contains() kelas HashSet, dan

Gunakan kaedah addAll() kelas HashSet untuk menambah semua elemen dalam koleksi ke koleksi lain HashSet ialah kelas pelaksanaan dalam rangka kerja koleksi Java Ia mewarisi daripada AbstractSet dan melaksanakan antara muka Set. HashSet ialah set tidak tertib berdasarkan jadual cincang, yang tidak membenarkan unsur pendua. Ia menyediakan banyak kaedah yang biasa digunakan untuk mengendalikan elemen dalam koleksi, salah satunya ialah kaedah addAll(). Fungsi kaedah addAll() adalah untuk menambah yang ditentukan

Sangat mudah untuk menambah elemen pada koleksi menggunakan kaedah HashSet.add() dalam Java Mari perkenalkan secara terperinci di bawah. HashSet ialah kelas koleksi dalam Java Ia mewarisi daripada kelas AbstractSet dan melaksanakan antara muka Set HashSet dicirikan sebagai tidak tertib dan tidak berulang, dan pelaksanaan asas adalah berdasarkan jadual cincang. Apabila menggunakan kaedah HashSet.add() untuk menambah elemen, anda perlu memberi perhatian kepada perkara berikut: HashSet hanya boleh menyimpan elemen jenis objek, bukan

Gunakan kaedah addAll() kelas HashSet untuk menambah set pada set lain HashSet ialah kelas koleksi dalam Java Ia melaksanakan antara muka Set dan dilaksanakan berdasarkan jadual cincang. Elemen pendua tidak dibenarkan dalam koleksi HashSet dan elemen dalam koleksi tidak tertib. Dalam pembangunan, kita selalunya perlu menambah elemen dari satu koleksi ke koleksi yang lain. Kelas HashSet menyediakan kaedah addAll() untuk melaksanakan fungsi ini dengan mudah. Di bawah ini kita akan melalui a

Gunakan kaedah retainAll() kelas HashSet untuk mendapatkan persilangan dua koleksi HashSet ialah kelas koleksi dalam Java yang digunakan untuk menyimpan satu set objek unik. Kaedah retainAll() ialah kaedah yang disediakan oleh kelas HashSet dan digunakan untuk mendapatkan persilangan dua HashSet. Di Java, koleksi ialah struktur data yang biasa digunakan yang boleh digunakan untuk menyimpan berbilang objek. HashSet ialah pelaksanaan konkrit yang biasa digunakan dalam kelas koleksi. Ia menyimpan dan mendapatkan semula objek melalui jadual cincang.

Gambarajah kelas HashSet Penerangan ringkas HashSet 1. HashSet melaksanakan antara muka Set 2. Lapisan bawah HashSet sebenarnya dilaksanakan oleh HashMap publicHashSet(){map=newHashMap();} 3. Null boleh disimpan, tetapi hanya boleh ada satu null 4.HashSet tidak Memastikan bahawa unsur-unsur adalah teratur (iaitu, ia tidak menjamin bahawa susunan unsur-unsur yang disimpan adalah konsisten dengan susunan unsur-unsur dikeluarkan. Hasil indeks ditentukan). selepas pencincangan. 5. Tidak boleh ada unsur pendua Mekanisme asas HashSet menerangkan bahawa lapisan bawah HashSet ialah HashMap, dan lapisan bawah HashMap ialah HashMap Ia adalah struktur tatasusunan + senarai terpaut + simulasi pokok merah-hitam tatasusunan + senarai terpaut /*