سؤال

لدي بعض الأسئلة حول طريقة AtomicReference.compareAndSet()، وفقًا للمستند، جاء فيه:

يضبط القيمة تلقائيًا على القيمة المحدثة المحددة إذا كانت القيمة الحالية == القيمة المتوقعة.

بقدر ما أفهم، == يقوم عامل التشغيل بمقارنة عنوان كائنين، إذا كان الأمر كذلك فكيف سيعمل في أمثلة كهذه

private AtomicReference<AccessStatistics> stats =
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0));
public void incrementPageCount(boolean wasError) {
    AccessStatistics prev, newValue;
    do {
        prev = stats.get();
        int noPages = prev.getNoPages() + 1;
        int noErrors = prev.getNoErrors;
        if (wasError) {
           noErrors++;
        }
        newValue = new AccessStatistics(noPages, noErrors);
    } while (!stats.compareAndSet(prev, newValue));
}

في مقتطف التعليمات البرمجية هذا، كيف يعرف JVM أي حقول AccessStatistics يجب مقارنتها في compareAndSet()؟في الحقيقة أنا فقط أتساءل كيف تعمل هذه الإستراتيجية بأكملها نظرًا لأن جافا لا تسمح بالتجاوز == على الاطلاق؟شكرا على أي تعليقات!

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

المحلول

كيف يعرف jvm حقول AccessStatistics التي سيتم مقارنتها في CompareAndSet()؟

لا.لا يتم مقارنة الحقول الموجودة في الكائن.انها مجرد مقارنة مرجع للكائن وهو ما تقوله الوثائق.هذه هي الطريقة التي AtomicReference أعمال الفصل.كما ذكرت من javadocs, يستخدم == وليس ال equals() طريقة.

يضبط القيمة تلقائيًا على القيمة المحدثة المحددة إذا كانت القيمة الحالية == القيمة المتوقعة.

جميع ال Atomic* الطبقات لها وظائف مماثلة.يسمح لك بتعيين القيم بشكل ذري مع التأكد من أن مؤشر ترابط آخر لا يحل محل القيمة الخاصة بك.مع compareAndSet(...) يجب عليك تحديد مرجع الكائن الحالي للتأكد من أنك تقوم بالتحديث كما هو متوقع.

في مقتطف التعليمات البرمجية الخاص بك، يحاول الإضافة إلى كائن إحصائيات الوصول غير القابل للتغيير.لذا فهو يحصل على القيمة الحالية، ويضيف إليها، ثم يخزن الإحصائية الجديدة في المرجع.إذا تم تخزين موضوع آخر إنه احصائيات بين ذلك الوقت, ثم compareAndSet سيعود كاذبًا ويتكرر ويحاول مرة أخرى.هذا يحل ظروف السباق دون الحاجة إلى الحصول على synchronized حاجز.

نصائح أخرى

لا يقوم JVM بمقارنة الحقول على الإطلاق.هو - هي فقط يقارن ما إذا كان هو نفس المرجع أم لا، أو نفس المؤشر في الذاكرة، أو ما تريد تسميته.

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