سؤال

لقد كنت أقرأ من أجل التزامن منذ الأمس ولا أعرف الكثير من الأشياء ...لكن بعض الأمور بدأت تتضح..
أفهم لماذا لا يكون قفل التحقق المزدوج آمنًا (أتساءل ما هي احتمالية حدوث حالة نادرة) ولكن التقلب يعمل على إصلاح المشكلة في 1.5 +....
لكني أتساءل عما إذا كان هذا يحدث مع putifAbsent

يحب...

myObj = new myObject("CodeMonkey");
cHashM.putIfAbsent("keyy",myObj);  

ثم هل هذا يضمن ذلك myObj سيتم البادئة بنسبة 100٪ عندما يقوم مؤشر ترابط آخر بـ cHashM.get() ؟؟؟؟لأنه قد يحتوي على مرجع لم تتم تهيئته بالكامل (مشكلة قفل التحقق المزدوج)

هل كانت مفيدة؟

المحلول

إذا استدعيت concurrentHashMap.get(key) وتقوم بإرجاع كائن، ويتم ضمان تهيئة هذا الكائن بالكامل.سيحصل كل وضع (أو putIfAbsent) على قفل خاص بالدلو وسيقوم بإلحاق العنصر بإدخالات الجرافة.

يمكنك الآن الاطلاع على الكود وملاحظة أن طريقة get لا تحصل على نفس القفل.لذلك يمكنك القول بأنه يمكن أن تكون هناك قراءة قديمة، وهذا ليس صحيحًا أيضًا.والسبب هنا هو أن القيمة داخل الإدخال نفسه متقلبة.لذلك سوف تكون متأكدًا من حصولك على أحدث المعلومات.

نصائح أخرى

putIfAbsent طريقة في ConcurrentHashMap هي طريقة التحقق من الغياب ثم التعيين.إنها عملية ذرية.ولكن للإجابة على الجزء التالي:"ثم هل يضمن هذا أن myObj سيتم تمهيده بنسبة 100٪ عندما يقوم مؤشر ترابط آخر بإجراء cHashM.get() "، سيعتمد ذلك على وقت وضع الكائن في HashMap.عادةً ما تكون هناك أسبقية "حدث قبل"، أي إذا حصل المتصل على الأولوية قبل وضع الكائن في الخريطة، إذن null سيتم إرجاعها، وإلا سيتم إرجاع القيمة.

الجزء ذو الصلة من الوثائق هو هذا:

تأثيرات تناسق الذاكرة:كما هو الحال مع المجموعات المتزامنة الأخرى ، فإن الإجراءات الموجودة في مؤشر ترابط قبل وضع كائن في خريطة متزامنة كمفتاح أو قيمة حدث قبل الوصول إلى الوصول أو إزالة هذا الكائن من ConcurrentMap في مؤشر ترابط آخر.

-- java.util.ConcurrentMap

لذا، نعم لديك الخاص بك يحدث من قبل علاقة.

أنا لست خبيرا في هذا، ولكن أبحث في التنفيذ Segment في ConcurrentHashMap أرى أن volatile مجال count يبدو أنه يستخدم لضمان الرؤية المناسبة بين المواضيع.جميع عمليات القراءة يجب أن تقرأ count الحقل وجميع عمليات الكتابة يجب أن تكتب إليه.من التعليقات في الصف:

Read operations can thus proceed without locking, but rely
on selected uses of volatiles to ensure that completed
write operations performed by other threads are
noticed. For most purposes, the "count" field, tracking the
number of elements, serves as that volatile variable
ensuring visibility.  This is convenient because this field
needs to be read in many read operations anyway:

   - All (unsynchronized) read operations must first read the
     "count" field, and should not look at table entries if
     it is 0.

   - All (synchronized) write operations should write to
     the "count" field after structurally changing any bin.
     The operations must not take any action that could even
     momentarily cause a concurrent read operation to see
     inconsistent data. This is made easier by the nature of
     the read operations in Map. For example, no operation
     can reveal that the table has grown but the threshold
     has not yet been updated, so there are no atomicity
     requirements for this with respect to reads.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top