Penelitian utama dalam artikel ini adalah konten yang relevan dari penggunaan ConcurrentMap.putIfAbsent(key,value) , sebagai berikut.
Skenario semacam ini sering ditemui dalam bisnis. ConcurrentMap bersamaan dipertahankan secara global. Setiap kunci peta sesuai dengan suatu objek, dan objek ini perlu dibuat hanya sekali. Jika nilai yang sesuai dengan kunci dalam peta tidak ada, itu akan dibuat, jika tidak, itu akan dikembalikan secara langsung.
Mari kita lihat kode terlebih dahulu:
Public static locale getInstance (bahasa string, negara string, varian string) {// ... string key = some_string; Local locale = map.get (key); if (locale == null) {locale = lokal baru (bahasa, negara, varian); peta.put (kunci, lokal); } mengembalikan lokal; } Apa yang perlu dilakukan kode ini adalah:
Kami berharap bahwa setiap kali metode GetInstance dipanggil, kami harus memastikan bahwa kunci yang sama mengembalikan referensi objek lokal yang sama. Bisakah kode ini mencapai persyaratan ini?
Jawabannya adalah: Persyaratan dapat dipenuhi dalam lingkungan satu utamanya, tetapi akan ada masalah keselamatan utas di lingkungan multi-threaded, yaitu, tidak dapat dijamin bahwa kunci yang sama dalam konkurensi akan mengembalikan referensi objek lokal yang sama.
Ini karena ada kebiasaan dalam kode di atas yang disebut operasi put-if-absent [1], dan operasi ini memiliki kondisi balapan:
if (locale == null) {locale = lokal baru (bahasa, negara, varian); peta.put (kunci, lokal); } Karena setelah utas selesai menilai lokal == NULL, memang benar untuk menempatkan nilai di peta. Utas lain mungkin sudah selesai menempatkan operasi di peta. Saat melakukan operasi lagi, objek lokal yang sesuai dengan kunci yang sama ditimpa, dan akhirnya referensi lokal dari kunci yang sama yang dikembalikan oleh metode GetInstance tidak akan konsisten. Oleh karena itu, operasi put-if-absen pada peta tidak aman (utas aman).
Untuk mengatasi masalah ini, Java 5.0 memperkenalkan antarmuka ConcurrentMap, di mana operasi put-if-absen ada dalam bentuk metode atom putIfAbsent(K key, V value) . Seperti yang ditulis Javadoc:
Saat menambahkan pasangan nilai kunci ke concurrenthashmap, pertama-tama akan menentukan apakah pasangan nilai kunci sudah ada.
Revisi metode di atas:
Public static locale getInstance (bahasa string, negara string, varian string) {// ... string key = some_string; Local locale = map.get (key); if (locale == null) {locale = lokal baru (bahasa, negara, varian); peta.putifabsent (kunci, lokal); } mengembalikan lokal; } Kode ini menggunakan bentuk peta yang bersamaan (ConcurrentMap, ConcurrenthashMap), dan hanya menggunakan map.putIfAbsent(key, locale) . Ini juga tidak menjamin bahwa kunci yang sama mengembalikan referensi objek lokal yang sama.
Kesalahan di sini adalah bahwa metode putifabsent memiliki nilai pengembalian, dan nilai pengembalian penting.
Oleh karena itu, saat menggunakan metode putifabsent, ingatlah untuk menilai nilai pengembalian.
Public static locale getInstance (bahasa string, negara string, varian string) {// ... string key = some_string; Local locale = map.get (key); if (locale == null) {locale = lokal baru (bahasa, negara, varian); Locale tmp = map.putifabsent (kunci, lokal); if (tmp! = null) {locale = tmp; }} mengembalikan lokal; } Impor java.util.map; impor java.util.concurrent.concurrenthashMap; tes kelas publik {public static void main (string [] args) {// uji currentHashMap.putifabsent () peta <long, string> clientmap = concurrenthashMap new concurrenthashMap <); out.out.out.out pertama "); System.out.println (" ClientMap: " + ClientMap); System.out.println (); // Tambahkan catatan baru di System ClientMap yang kosong.out.println (" Tambahkan catatan baru di klien KOFFICE "); System.out.println (" Tambahkan klien sebelumnya klien: " + neto; clientmap.putIfabSent (netid, str1); system.out.println ("Tambahkan ClientMap sebelumnya:" + clientmap); System.out.println ("Lihat Hasil Nilai Pengembalian:" + Hasil); System.out.println (); // Ulangi System.out.println ("Ulangi Rekaman Terakhir." result2 = clientmap.putifabsent (netid, str1); System.out.println ("Setelah menambahkan ClientMap:" + ClientMap); System.out.println ("Lihat Hasil Nilai Pengembalian:" + Hasil2); System.out.println ();}}}Di atas adalah seluruh konten artikel ini tentang contoh penggunaan concurrentmap.putifabsent (kunci, nilai) dan saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!