تم تقديم ConcurrenthashMap (CHM لفترة قصيرة) حديثًا في Java 1.5 كبديل للهاش ، وهو عضو مهم في الحزمة المتزامنة. قبل Java 1.5 ، إذا كنت ترغب في تنفيذ خريطة يمكن استخدامها بأمان في برامج متعددة الخيوط ومتزامنة ، فيمكنك الاختيار فقط من الخريطة القابلة للهاوية والمزامنة ، لأن HashMap ليس آمنًا للموضوع. ولكن بعد تقديم CHM ، لدينا خيار أفضل. إن CHM ليس آمنًا فقط ، بل يعمل أيضًا بشكل أفضل من علامة التجزئة والمزامنة. بالمقارنة مع Hashtable و SynchronizedMap ، يتم قفل الخريطة بأكملها ، وتغلق CHM فقط بعض الخرائط. يتيح CHM عمليات القراءة المتزامنة مع الحفاظ على تكامل البيانات أثناء عمليات الكتابة من خلال أقفال متزامنة. لقد تعلمنا أساسيات CHM في أفضل 5 مجموعات متزامنة Java من JDK 5 و 6. في هذه المدونة ، سأقدم النقاط التالية:
تنفيذ concurrenthashmap في جافا
يقدم CHM تجزئة ويوفر جميع الميزات التي تدعمها علامة التجزئة. في CHM ، يتم دعم Multithreading لقراءة الخريطة ولا يتطلب أي حظر. ويرجع ذلك إلى حقيقة أن CHM يقسم الخريطة إلى أجزاء مختلفة ، مما يؤدي إلى قفل جزء منها فقط عند إجراء عملية التحديث. وفقًا لمستوى التزامن الافتراضي ، يتم تقسيم الخريطة إلى 16 جزءًا ويتم التحكم فيها بواسطة أقفال مختلفة. هذا يعني أنه يمكن لما يصل إلى 16 مؤشرات ترابط الكتابة تشغيل الخريطة في نفس الوقت. فقط تخيل أنه من بين موضوع واحد فقط يدخل إلى 16 مؤشر ترابط الكتابة الذي يدخل في نفس الوقت (قراءة المواضيع غير محدودة تقريبًا) ، فإن تحسين الأداء واضح. ومع ذلك ، نظرًا لأن بعض عمليات التحديث ، مثل PUT () ، إزالة () ، putall () ، و clear () ، قفل العملية فقط ، لا يمكن أن تضمن عملية البحث أن أحدث النتائج سيتم إرجاعها.
هناك نقطة مهمة أخرى وهي أنه عندما يكون التكرار على CHM ، فإن التكرار الذي تم إرجاعه بواسطة KeyySet يكون متسقًا بشكل ضعيف ومآمن للفشل ، وقد لا يعيد بعض التغييرات الحديثة. أثناء اجتياز ، إذا كان المحتوى الموجود على الصفيف الذي تم اجتيازه ، فلن يتم طرح استثناء ConversIdificationExceptoin.
مستوى التزامن الافتراضي لـ CHM هو 16 ، ولكن يمكن تغييره بواسطة مُنشئ عند إنشاء CHM. ليس هناك شك في أن مستوى التزامن يمثل عدد عمليات التحديث المتزامنة ، لذلك إذا قام عدد قليل من مؤشرات الترابط فقط بتحديث الخريطة ، فمن المستحسن تعيين مستوى التزامن منخفض. بالإضافة إلى ذلك ، يستخدم CHM أيضًا إعادة إينترانتلوك لقفل الأجزاء.
مثال على طريقة concurrenthashmap putifabsent في جافا
في كثير من الأحيان نريد إدراج عناصر عندما لا تكون موجودة ، وعادة ما نكتب رمز مثل ما يلي
Synchronized (map) {if (map.get (key) == null) {return map.put (key ، value) ؛ } آخر {return map.get (key) ؛ }}الكود أعلاه سهل الاستخدام في hashmap و hashtable ، ولكن هناك خطر حدوث أخطاء في CHM. وذلك لأن CHM لا يغلق الخريطة بأكملها أثناء عملية PUT ، لذلك عندما يتم وضع مؤشر ترابط (K ، V) ، تحصل مكالمات مؤشر ترابط أخرى على (k) والحصول على خالية ، مما سيؤدي إلى كتابة قيمة لخيط واحد من خلال قيمة خيط آخر. بالطبع ، يمكنك تغليف الكود في كتلة رمز متزامنة ، والتي ستجعل الرمز المفرد ، على الرغم من آمن مؤشرات الترابط. تقوم طريقة putifabsent (المفتاح ، القيمة) التي توفرها CHM بنفس الوظيفة ذرية ، مع تجنب خطر منافسة الخيط أعلاه.
متى تستخدم concurrenthashmap
يعد CHM مناسبًا عندما يتجاوز عدد القراء عدد القراء ، وعندما يكون عدد القراء أكبر من أو يساوي القارئ ، يكون أداء CHM أقل من خريطة الهاشتو والمتزامنة. هذا لأنه عندما يتم قفل الخريطة بأكملها ، تنتظر عملية القراءة الخيط الذي يؤدي عملية الكتابة إلى نفس الجزء لإنهائه. CHM مناسب لصنع ذاكرة التخزين المؤقت ، وتم تهيئته في بداية البرنامج ، ويمكن الوصول إليه بعد ذلك بواسطة مؤشرات ترابط متعددة. كما يوضح Javadoc ، فإن CHM بديل جيد لـ Hashtable ، ولكن تذكر أن CHM لديها تزامن أقل قليلاً من علامة التصنيف.
لخص
الآن نحن نعرف ما هو ConcurrenthashMap ومتى نستخدم concurrenthashmap. دعنا نراجع بعض النقاط الرئيسية لـ CHM.
ما سبق هو سيناريوهات التنفيذ والاستخدام لـ CHM في Java ، وآمل أن تتمكن من مساعدة الجميع! شكرا لك على دعمك لهذا الموقع!