HashSet didasarkan pada HashMap.
Jika kita melihat HashSet<E>
implementasi, semuanya dikelola di bawah HashMap<E,Object>
.
<E>
digunakan sebagai kunci dari HashMap
.
Dan kita tahu bahwa HashMap
itu tidak aman. Itu sebabnya kami ada ConcurrentHashMap
di Jawa.
Berdasarkan ini, saya bingung mengapa kita tidak memiliki ConcurrentHashSet yang harus didasarkan pada ConcurrentHashMap
?
Apakah ada hal lain yang saya lewatkan? Saya perlu menggunakan Set
dalam lingkungan multi-utas.
Juga, Jika saya ingin membuat milik saya sendiri, ConcurrentHashSet
bisakah saya mencapainya dengan hanya mengganti HashMap
to ConcurrentHashMap
dan membiarkan sisanya seperti apa adanya?
java
collections
concurrency
hashmap
hashset
Talha Ahmed Khan
sumber
sumber
ConcurrentSkipListSet
dibangun di atasConcurrentSkipListMap
, yang mengimplementasikanConcurrentNavigableMap
danConcurrentMap
.Jawaban:
Tidak ada tipe bawaan
ConcurrentHashSet
karena Anda selalu dapat memperoleh satu set dari peta. Karena ada banyak jenis peta, Anda menggunakan metode untuk menghasilkan satu set dari peta yang diberikan (atau kelas peta).Sebelum ke Java 8, Anda menghasilkan hash bersamaan yang didukung oleh peta hash bersamaan, dengan menggunakan
Collections.newSetFromMap(map)
Di Jawa 8 (ditunjukkan oleh @ Matt), Anda bisa mendapatkan konkuren hash set pandangan via
ConcurrentHashMap.newKeySet()
. Ini sedikit lebih sederhana daripada yang lamanewSetFromMap
yang mengharuskan Anda untuk memasukkan objek peta kosong. Tetapi khusus untukConcurrentHashMap
.Bagaimanapun, desainer Java bisa saja membuat set antarmuka baru setiap kali antarmuka peta baru dibuat, tetapi pola itu tidak mungkin ditegakkan ketika pihak ketiga membuat peta mereka sendiri. Lebih baik memiliki metode statis yang memperoleh set baru; pendekatan itu selalu berhasil, bahkan ketika Anda membuat implementasi peta Anda sendiri.
sumber
ConcurrentHashMap
, Anda kehilangan manfaat yang akan Anda dapatkanConcurrentHashMap
?newSetFromMap
Implementasi ditemukan mulai pada baris 3841 di docjar.com/html/api/java/util/Collections.java.html . Itu hanya pembungkus ....Collections.newSetFromMap
buat aSetFromMap
. misalnyaSetFromMap.removeAll
metode delegasi keKeySetView.removeAll
, yang mewarisi dariConcurrentHashMap$CollectionView.removeAll
. Metode ini sangat tidak efisien dalam elemen pemindahan massal. bayangkanremoveAll(Collections.emptySet())
melintasi semua elemenMap
tanpa melakukan apa pun. MemilikiConcurrentHashSet
yang diterapkan dengan benar akan lebih baik dalam banyak kasus.sumber
Dengan Guava 15 Anda juga dapat menggunakan:
sumber
Seperti yang disebutkan oleh Ray Toal , ini semudah:
sumber
ConcurrentHashMap
.Sepertinya Java menyediakan implementasi Set bersamaan dengan ConcurrentSkipListSet -nya . Sebuah SkipList Set hanya jenis khusus dari pelaksanaan set. Itu masih mengimplementasikan antarmuka Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet. Ini mungkin bekerja untuk Anda jika Anda hanya perlu mengatur antarmuka.
sumber
ConcurrentSkipListSet
elemen harusComparable
ConcurrentSkipListSet
kecuali Anda menginginkanSortedSet
. Operasi biasa seperti menambah atau menghapus harus O (1) untuk aHashSet
, tetapi O (log (n)) untuk aSortedSet
.Seperti yang ditunjukkan oleh ini , cara terbaik untuk mendapatkan HashSet yang mampu melakukan konkurensi adalah dengan cara
Collections.synchronizedSet()
Ini bekerja untuk saya dan saya belum melihat ada orang yang benar-benar menunjuk ke sana.
EDIT Ini kurang efisien daripada solusi yang saat ini disetujui, seperti yang ditunjukkan Eugene, karena itu hanya membungkus set Anda ke dekorator yang disinkronkan, sementara yang
ConcurrentHashMap
sebenarnya mengimplementasikan konkurensi tingkat rendah dan itu dapat mendukung Set Anda dengan baik. Jadi terima kasih kepada Tn. Stepanenkov karena menjelaskannya.http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-
sumber
synchronizedSet
metode hanya menciptakan dekorator bawahCollection
untuk metode bungkus yang bisa benang-aman dengan sinkronisasi seluruh koleksi. TetapiConcurrentHashMap
diimplementasikan menggunakan algoritma non-blocking dan sinkronisasi "tingkat rendah" tanpa kunci seluruh koleksi. Jadi pembungkus dariCollections.synchronized
... lebih buruk di lingkungan multi-utas untuk alasan kinerja.Anda dapat menggunakan jambu biji
Sets.newSetFromMap(map)
untuk mendapatkannya. Java 6 juga memiliki metode itu dijava.util.Collections
sumber
sumber
Mengapa tidak menggunakan: CopyOnWriteArraySet dari java.util.concurrent?
sumber