سؤال

ما هو الفرق بين lazySet و set طرق AtomicIntegerب ال توثيق ليس لديه الكثير ليقوله lazySet:

في نهاية المطاف يحدد القيمة المحددة.

يبدو أن القيمة المخزنة لن يتم تعيينها على الفور إلى القيمة المطلوبة ولكن من المقرر بدلا من ذلك أن يتم تعيين بعض الوقت في المستقبل. ولكن، ما هو الاستخدام العملي لهذه الطريقة؟ أي مثال؟

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

المحلول

استشهد مباشرة من "JDK-6275329: إضافة طرق Lazyset إلى الطبقات الذرية":

على الأرجح آخر متابعة JSR166 الصغير ل MUSTANG، أضفنا طريقة "Lazyset" للصفات الذرية (Atomicinteger، AtomicReference، إلخ). هذه طريقة مخصصة مفيدة في بعض الأحيان عند ضبط رمز الدقيق باستخدام هياكل بيانات غير حظر. هذه الدلالات هي أن الكتابة مضمونة بعدم إعادة طلبها مع أي كتابة سابقة، ولكن قد يتم إعادة ترتيبها بالعمليات اللاحقة (أو معادلها، قد لا تكون مرئية من المواضيع الأخرى) حتى يحدث بعض الإجراءات المتقلبة أو المزامنة الأخرى).

حالة الاستخدام الرئيسية مخصصة لإلغاء حقول العقد في هياكل البيانات غير المضرورة فقط من أجل تجنب الاحتفاظ بالقمامة على المدى الطويل؛ ينطبق عندما تكون غير ضارة إذا كانت الخيوط الأخرى نرى القيم غير الفارغة لفترة من الوقت، لكنك ترغب في التأكد من أن الهياكل في نهاية المطاف. في مثل هذه الحالات، يمكنك الحصول على أداء أفضل من خلال تجنب تكاليف الكتابة المضطربة NULL. هناك عدد قليل من حالات الاستخدام الأخرى على طول هذه الخطوط للذروم الذرية غير المرجعية أيضا، لذلك يتم دعم الطريقة في جميع فئات ATOMICX.

بالنسبة للأشخاص الذين يرغبون في التفكير في هذه العمليات من حيث الحواجز على مستوى الماكينة على المعالجات المشتركة، يوفر Lazyset حاجز متاجر المتجر مسبقا (أي إما غير مرجع أو رخيص جدا على المنصات الحالية)، ولكن لا حاجز تحميل مخزن (وهو عادة جزء باهظ الثمن من الكتابة المتقلبة).

نصائح أخرى

يمكن استخدام Lazyset لاتصالات RMW Inter Thret Trading، لأن XCHG هو ذرية، أما بالنسبة للوضوح، عندما تقوم عملية مؤشر الترابط الكاتب بتعديل موقع خط ذاكرة التخزين المؤقت، سترى معالج القارئ مؤشر ترابطه في القراءة التالية، لأن بروتوكول تماسك مخبأ من Intel CPU سوف Garantee يعمل Lazyset، ولكن سيتم تحديث خط ذاكرة التخزين المؤقت في القراءة التالية، مرة أخرى، يجب أن يكون وحدة المعالجة المركزية حديثة بما فيه الكفاية.

http://sc.tamu.edu/systems/eos/nehalem.pdf.بالنسبة إلى Nehalem وهو عبارة عن منصة متعددة المعالجات، تتمتع المعالجات بالقدرة على "سنوب" (Evesdrop) عن حافلة العناوين الخاصة بالمعالج الأخرى إلى ذاكرة النظام وإلى مخابئها الداخلية. يستخدمون هذه القدرة التطفل على الحفاظ على مبخبهم الداخليين بما يتوافق مع ذاكرة النظام ومع ذاكرة التخزين المؤقت في معالجات غير متصلة أخرى. إذا كان من خلال مطلي معالج واحد يكتشف أن معالج آخر يعتزم الكتابة إلى موقع الذاكرة التي تم تخزينها حاليا في حالة مشتركة، فإن معالج الطفلا سوف يبطل كتلة ذاكرة التخزين المؤقت لها إجباره على أداء خط ذاكرة التخزين المؤقت تعبئ في المرة التالية التي تصل إلى نفس موقع الذاكرة وبعد

Oracle Hotspot JDK ل X86 CPU Architecture->

lazyset == غير آمنة. putorderedlong == XCHG RW (ASM التعليمات التي تعمل كحاجز ناعم تكلف 20 دورة على Nehelem Intel CPU)

على X86 (x86_64) مثل هذا الحاجز هو أداء أرخص بكثير من المتقلب أو atomiclong getandadd،

في منتج واحد، يمكن لسيناريو قائمة انتظار مستهلك واحد، يمكن أن يجبر حاجز XCHG الناعم على خط الرموز قبل أن يحدث Lazyset (التسلسل + 1) لمؤشر منتج المنتج قبل أي رمز مؤشر ترابط المستهلك الذي سيستهلك البيانات الجديدة (العمل على) البيانات الجديدة، بالطبع سيحتاج مؤشر ترابط المستهلك إلى التحقق من ذلك بشكل مغمول أنه تم زيادة تسلسل المنتجين من قبل واحد بالضبط باستخدام مقارنة (تسلسل أو تسلسل + 1).

لقد تتبعت بعد شفرة المصدر الساخنة للعثور على التعيين الدقيق في LAZYSET إلى رمز CPP:http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe.cpp.UNSAFE_SETORDEREDLONG -> SET_FILD_VOLATILE التعريف -> orderAffess: servery_store_fence. ل x86_64، ordamess: يتم تعريف الإصدار_Store_Fence على أنه باستخدام تعليمات XCHG.

يمكنك أن ترى كيف يتم تعريفه بالضبط في JDK7 (Doug Lea يعمل على بعض الأشياء الجديدة ل JDK 8):http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/linux_x86/vm/orderaccess_linux_x86.inline.hpp.

يمكنك أيضا استخدام HDIS لتفكيك تجميع رمز LAZYSET في العمل.

هناك سؤال آخر متعلقا:هل نحتاج إلى Mfence عند استخدام XCHG

يمكن العثور على مناقشة أوسع من أصول وأداة مساعدة LAZYSET والبوطير الأساسي هنا: http://psy-lob-saw.blogspot.co.uk 15/12/atomiclazyset-is-performance-win-for.html.

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

عند قراءة القيمة التي تنتهي بها دائما القيام بقراءة متقلبة (مع الذرية * .get () في أي حال).

تقدم Lazyset كاتبا واحدا لآلية مكتبة متقلبة ثابتة، أي أنها مشروعة تماما لكاتب واحد لاستخدام Lazyset لزيادة عداد، وتزيد من المواضيع الزائدة نفس العداد سيكون لحل الكتابة المتنافسة باستخدام CAS، وهذا هو بالضبط ما يحدث تحت أغلفة الذرية * لإبداع.

من ملخص حزمة الذرية المتزامنة

lazyset. لديه تأثيرات ذاكرة الكتابة (تعيين) متغير متقلب إلا أنه يسمح بإجراءات الذاكرة التالية (ولكن ليس قبل سابقا) التي لا تفرض أنفسهم قيودا إعادة ترتيب مع الكتب غير المتقلبة العادية. من بين سياقات الاستخدام الأخرى، قد يتم تطبيق LAZYSET عند إتل نوم، من أجل جمع القمامة، مرجع لا يمكن الوصول إليه مرة أخرى.

إذا كنت فضوليا حول Lazyset، فأنت مدين بنفسك تفسيرات أخرى أيضا

تتابع تأثيرات الذاكرة للوصول وتحديثات الذرية الذرية عموما قواعد التقلب، كما هو مذكور في القسم 17.4 من مواصفات لغة Java ™.

احصل على لديه آثار الذاكرة لقراءة متغير متقلب.

جلس لديه تأثيرات ذاكرة الكتابة (تعيين) متغير متقلب.

lazyset. لديه تأثيرات ذاكرة الكتابة (تعيين) متغير متقلب إلا أنه يسمح بإجراءات الذاكرة التالية (ولكن ليس قبل سابقا) التي لا تفرض أنفسهم قيودا إعادة ترتيب مع الكتب غير المتقلبة العادية. من بين سياقات الاستخدام الأخرى، قد يتم تطبيق LAZYSET عند إتل نوم، من أجل جمع القمامة، مرجع لا يمكن الوصول إليه مرة أخرى.

ضعيف يقرأ بشكل جذري وتكتب مشروطا متغيرا ولكنه لا يخلق أي حدث - وقبل الأمر، لذلك لا يوفر أي ضمانات فيما يتعلق بالقراءة السابقة أو اللاحقة وكتابة أي متغيرات بخلاف هدف الضعف الضعيف. مقارنة وجميع عمليات القراءة والتحديث الأخرى مثل GetAndinCrument لها آثار الذاكرة لكل من متغيرات القراءة والكتابة المتقلبة.

هنا فهمي، تصحيح لي إذا كنت مخطئا: يمكنك التفكير lazySet() ك "شبه" متقلبة: إنه أساسا متغير غير متقلب من حيث القراءة من قبل المواضيع الأخرى، أي قد لا تكون القيمة التي حددتها Lazyset مرئية إلى مؤشرات ترابط أخرى. ولكن يصبح متقلبا عند حدوث عملية كتابة أخرى (قد تكون من مؤشرات الترابط الأخرى). التأثير الوحيد ل Lazyset يمكنني تخيله هو compareAndSet. وبعد لذلك إذا كنت تستخدم lazySet(), get() من المواضيع الأخرى قد لا تزال تحصل على القيمة القديمة، ولكن compareAndSet() سيكون لها دائما القيمة الجديدة لأنها عملية الكتابة.

إعادة: محاولة غبيها -

يمكنك التفكير في ذلك كوسيلة لعلاج حقل متقلب كما لو كان غير متقلب لمتجر معين (على سبيل المثال: المرجع = null؛) العملية.

هذا ليس دقيقا تماما، ولكن يجب أن يكون كافيا أنه يمكنك اتخاذ قرار بين "موافق، أنا حقا لا أهتم" و "هم، اسمحوا لي أن أفكر في ذلك قليلا".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top