البحث الرئيسي في هذه المقالة هو المحتوى ذي الصلة لاستخدام ConcurrentMap.putIfAbsent(key,value) ، على النحو التالي.
غالبًا ما يتم مواجهة هذا النوع من السيناريو في العمل. يتم الحفاظ على خريطة متزامنة متزامنة على مستوى العالم. يتوافق كل مفتاح الخريطة مع كائن ، ويجب إنشاء هذا الكائن مرة واحدة فقط. إذا كانت القيمة المقابلة للمفتاح في الخريطة غير موجودة ، فسيتم إنشاؤها ، وإلا فإنه سيتم إرجاعها مباشرة.
دعونا نلقي نظرة على الرمز أولاً:
GetInstance static static static (لغة السلسلة ، بلد السلسلة ، متغير السلسلة) {// ... string key = some_string ؛ locale locale = map.get (مفتاح) ؛ if (locale == null) {locale = new locale (language ، country ، variant) ؛ map.put (مفتاح ، لغة) ؛ } لغة العودة ؛ } ما يحتاجه هذا الرمز هو:
نتوقع أنه في كل مرة يتم استدعاء طريقة getInstance ، يجب علينا التأكد من أن المفتاح نفسه يعيد نفس مرجع الكائن المحلي. هل يمكن لهذا الرمز تحقيق هذا المطلب؟
الجواب هو: يمكن تلبية المتطلبات في بيئة واحدة تراجعت ، ولكن ستكون هناك مشاكل في سلامة الخيوط في بيئة متعددة الخيوط ، أي أنه لا يمكن ضمان أن نفس المفتاح في التزامن سيعيد نفس مرجع الكائن المحلي.
هذا لأن هناك عادة في الكود أعلاه تسمى عملية Put-If-Absent [1] ، وهذه العملية لها حالة سباق:
if (locale == null) {locale = new locale (language ، country ، variant) ؛ map.put (مفتاح ، لغة) ؛ } لأنه بعد انتهاء موضوع الحكم == NULL ، فمن الصحيح وضع القيمة في الخريطة. قد تكون المواضيع الأخرى قد قامت بالفعل بعمليات وضع على الخريطة. عند القيام بعمليات وضع مرة أخرى ، يتم كتابة الكائن المحلي المقابل للمفتاح نفسه ، وأخيراً ، فإن مرجع المحطة لنفس المفتاح الذي تم إرجاعه بواسطة طريقة getInstance سيكون غير متناسق. لذلك ، فإن عملية PUT-IF-ABSENT على الخريطة ليست آمنة (مؤشر ترابط آمن).
لحل هذه المشكلة ، قدمت Java 5.0 واجهة ConcurrentMap ، حيث توجد عملية Put-If-Absent في شكل طريقة ذرية putIfAbsent(K key, V value) . كما يكتب جافادوك:
عند إضافة زوج القيمة الرئيسية إلى concurrenthashmap ، سيحدد أولاً ما إذا كان زوج القيمة الرئيسية موجودًا بالفعل.
مراجعة الطريقة أعلاه:
GetInstance static static static (لغة السلسلة ، بلد السلسلة ، متغير السلسلة) {// ... string key = some_string ؛ locale locale = map.get (مفتاح) ؛ if (locale == null) {locale = new locale (language ، country ، variant) ؛ map.putifabsent (مفتاح ، لغة) ؛ } لغة العودة ؛ } يستخدم هذا الرمز النموذج المتزامن للخريطة (ConcurrentMap ، ConcurrentHashMap) ، ويستخدم ببساطة عبارة map.putIfAbsent(key, locale) . هذا أيضًا لا يضمن أن نفس المفتاح يعيد مرجع كائن اللغة نفسه.
الخطأ هنا هو أن طريقة putifabsent لها قيمة إرجاع ، وقيمة الإرجاع مهمة.
لذلك ، عند استخدام طريقة putifabsent ، تذكر أن تحكم على قيمة الإرجاع.
GetInstance static static static (لغة السلسلة ، بلد السلسلة ، متغير السلسلة) {// ... string key = some_string ؛ locale locale = map.get (مفتاح) ؛ if (locale == null) {locale = new locale (language ، country ، variant) ؛ locale tmp = map.putifabsent (مفتاح ، لغة) ؛ if (tmp! = null) {locale = tmp ؛ }} لغة الإرجاع ؛ } استيراد java.util.map ؛ import java.util.concurrent.concurrenthashMap ؛ اختبار الفئة العامة {public static void main (string [] args) {// test currentHashMap.putifaBSent () خريطة <Ngt ، string> clientmap = concurrenthashmap <> أولاً ") ؛ system.out.println (" ClientMap: " + clientMap) ؛ system.out.println () ؛ // إضافة سجل جديد في system.out.out.println clientmap.putifabsent (netId ، str1) ؛ system.out.println ("إضافة عميل سابق:" + clientMap) ؛ system.out.println ("عرض قيمة الإرجاع:" + result) ؛ system.out.println () ؛ // تكرار إضافة system.out.println ("كرر السجل الأخير") result2 = clientMap.putifaBSent (netid ، str1) ؛ system.out.println ("بعد إضافة clientMap:" + clientMap) ؛ system.out.println ("عرض قيمة الإرجاع:" + result2) ؛ system.out.println () ؛}}ما ورد أعلاه هو المحتوى الكامل لهذه المقالة حول مثال الاستخدام لـ ConvalrentMap.Putifabsent (المفتاح ، القيمة) وآمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!