Apa perbedaan antara menggunakan kelas pembungkus SynchronizedMap
,, pada HashMap
dan ConcurrentHashMap
?
Apakah ini hanya dapat memodifikasi HashMap
sementara iterasi ( ConcurrentHashMap
)?
Apa perbedaan antara menggunakan kelas pembungkus SynchronizedMap
,, pada HashMap
dan ConcurrentHashMap
?
Apakah ini hanya dapat memodifikasi HashMap
sementara iterasi ( ConcurrentHashMap
)?
Jawaban:
Disinkronkan HashMap
:
Setiap metode disinkronkan menggunakan kunci level objek. Jadi metode get dan taruh di synchMap memperoleh kunci.
Mengunci seluruh koleksi adalah overhead kinerja. Sementara satu utas memegang kunci, tidak ada utas lain yang dapat menggunakan koleksi.
ConcurrentHashMap
diperkenalkan di JDK 5.
Tidak ada penguncian di tingkat objek, Penguncian pada granularity yang jauh lebih halus. Untuk a ConcurrentHashMap
, kuncinya mungkin berada pada level bucket hashmap.
Efek dari penguncian tingkat yang lebih rendah adalah Anda dapat memiliki pembaca dan penulis bersamaan yang tidak mungkin untuk koleksi yang disinkronkan. Ini mengarah pada skalabilitas yang jauh lebih banyak.
ConcurrentHashMap
tidak melempar ConcurrentModificationException
jika satu utas mencoba memodifikasinya sementara yang lain mengulanginya.
Artikel ini Java 7: HashMap vs ConcurrentHashMap adalah bacaan yang sangat bagus. Sangat dianjurkan.
ConcurrentHashMap
's size()
hasil bisa keluar dari tanggal. size()
diizinkan untuk mengembalikan perkiraan alih-alih hitungan yang tepat menurut buku "Java Concurrency in Practice". Jadi metode ini harus digunakan dengan hati-hati.
Jawaban singkatnya:
Kedua peta adalah implementasi Map
antarmuka yang aman. ConcurrentHashMap
diimplementasikan untuk throughput yang lebih tinggi dalam kasus di mana konkurensi tinggi diharapkan.
Artikel Brian Goetz tentang ide di balik ConcurrentHashMap
adalah bacaan yang sangat bagus. Sangat dianjurkan.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
aman utasnya tanpa menyinkronkan seluruh peta. Membaca dapat terjadi sangat cepat saat menulis dilakukan dengan kunci.
Kita dapat mencapai keamanan utas dengan menggunakan ConcurrentHashMap dan sinkronisasiHashmap. Tetapi ada banyak perbedaan jika Anda melihat arsitektur mereka.
Ini akan mempertahankan kunci di tingkat objek. Jadi jika Anda ingin melakukan operasi seperti put / get maka Anda harus mendapatkan kunci terlebih dahulu. Pada saat yang sama, utas lainnya tidak diizinkan untuk melakukan operasi apa pun. Jadi pada suatu waktu, hanya satu utas yang dapat beroperasi pada ini. Jadi waktu tunggu akan meningkat di sini. Kita dapat mengatakan bahwa kinerjanya relatif rendah ketika Anda membandingkan dengan ConcurrentHashMap.
Ini akan mempertahankan kunci di tingkat segmen. Ini memiliki 16 segmen dan mempertahankan tingkat concurrency sebagai 16 secara default. Jadi pada suatu waktu, 16 utas dapat dapat beroperasi di ConcurrentHashMap. Selain itu, operasi baca tidak memerlukan kunci. Jadi sejumlah utas dapat melakukan operasi get di atasnya.
Jika thread1 ingin melakukan operasi put di segmen 2 dan thread2 ingin melakukan operasi put di segmen 4 maka diizinkan di sini. Berarti, 16 utas dapat melakukan operasi pembaruan (menaruh / menghapus) pada ConcurrentHashMap sekaligus.
Sehingga waktu tunggu akan lebih sedikit di sini. Oleh karena itu kinerjanya relatif lebih baik daripada sinkronisasi peta.
Keduanya adalah versi HashMap yang disinkronkan, dengan perbedaan dalam fungsi inti dan struktur internal mereka.
ConcurrentHashMap terdiri dari segmen internal yang dapat dilihat sebagai HashMaps independen Secara Konseptual. Semua segmen tersebut dapat dikunci dengan utas terpisah dalam eksekusi bersamaan tinggi. Jadi, banyak utas bisa mendapatkan / menempatkan pasangan nilai kunci dari ConcurrentHashMap tanpa memblokir / menunggu satu sama lain. Ini diterapkan untuk throughput yang lebih tinggi.
sedangkan
Collections.synchronizedMap () , kami mendapatkan versi tersinkronisasi dari HashMap dan diakses dengan cara memblokir. Ini berarti jika beberapa utas mencoba mengakses Peta yang disinkronkan pada saat yang sama, mereka akan diizinkan untuk mendapatkan / menempatkan pasangan nilai kunci satu per satu secara tersinkronisasi.
ConcurrentHashMap
menggunakan mekanisme penguncian berbutir halus yang dikenal lock stripping
untuk memungkinkan tingkat akses bersama yang lebih besar. Karena ini memberikan konkurensi dan skalabilitas yang lebih baik .
Juga iterator kembali untuk ConcurrentHashMap
yang lemah konsisten bukannya gagal teknik yang cepat digunakan oleh Synchronized HashMap.
Metode SynchronizedMap
memegang kunci pada objek, sedangkan di ConcurrentHashMap
sana ada konsep "penguncian kunci" di mana kunci disimpan pada ember isinya. Sehingga meningkatkan skalabilitas dan kinerja.
ConcurrentHashMap:
1) Kedua peta adalah implementasi antarmuka Map yang aman.
2) ConcurrentHashMap diimplementasikan untuk throughput yang lebih tinggi dalam kasus di mana konkurensi tinggi diharapkan.
3) Tidak ada penguncian di tingkat objek.
Peta Hash Tersinkronisasi:
1) Setiap metode disinkronkan menggunakan kunci level objek.
ConcurrentHashMap memungkinkan akses bersamaan ke data. Seluruh peta dibagi menjadi beberapa segmen.
Baca operasi yaitu. get(Object key)
tidak disinkronkan bahkan di tingkat segmen.
Tetapi menulis operasi yaitu. remove(Object key), get(Object key)
memperoleh kunci di tingkat segmen. Hanya sebagian dari seluruh peta yang dikunci, utas lainnya masih dapat membaca nilai dari berbagai segmen kecuali yang dikunci.
SynchronizedMap di sisi lain, memperoleh kunci di level objek. Semua utas harus menunggu utas saat ini terlepas dari operasi (Baca / Tulis).
Tes kinerja sederhana untuk ConcurrentHashMap vs Synchronized HashMap
. Aliran uji memanggil put
satu utas dan memanggil get
tiga utas Map
bersamaan. Seperti @trshiv katakan, ConcurrentHashMap memiliki throughput dan kecepatan yang lebih tinggi untuk operasi pembacaan tanpa kunci. Hasilnya adalah ketika waktu operasi selesai 10^7
, ConcurrentHashMap 2x
lebih cepat dari Sinkronisasi HashMap.
SynchronizedMap
dan ConcurrentHashMap
keduanya kelas benang aman dan dapat digunakan dalam aplikasi multithreaded, perbedaan utama di antara mereka adalah tentang bagaimana mereka mencapai keamanan benang.
SynchronizedMap
memperoleh kunci pada seluruh instance Peta, sementara ConcurrentHashMap
membagi instance Peta menjadi beberapa segmen dan penguncian dilakukan pada mereka.
Sesuai java doc's
Hashtable dan Collections.synchronizedMap (HashMap baru ()) disinkronkan. Tapi ConcurrentHashMap adalah "bersamaan".
Kumpulan bersamaan adalah thread-safe, tetapi tidak diatur oleh kunci pengecualian tunggal.
Dalam kasus tertentu ConcurrentHashMap, ia dengan aman mengizinkan sejumlah pembacaan bersamaan sekaligus sejumlah merdu menulis bersamaan. Kelas "Sinkronisasi" dapat berguna ketika Anda harus mencegah semua akses ke koleksi melalui satu kunci, dengan mengorbankan skalabilitas yang lebih buruk.
Dalam kasus lain di mana beberapa utas diharapkan untuk mengakses koleksi umum, versi "bersamaan" biasanya lebih disukai. Dan koleksi yang tidak disinkronkan lebih disukai ketika salah satu koleksi tidak dibagikan, atau hanya dapat diakses saat memegang kunci lain.
Hashtable
danSynchronized HashMap
?