ArrayBlockingQueue में, स्थानीय अंतिम चर में अंतिम सदस्य क्षेत्र की प्रतिलिपि क्यों बनाएं?


81

ArrayBlockingQueueसभी तरीकों में , ताला की आवश्यकता होती है, इसे finalकॉल करने से पहले एक स्थानीय चर पर कॉपी करें lock()

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        if (count == items.length)
            return false;
        else {
            insert(e);
            return true;
        }
    } finally {
        lock.unlock();
    }
}

फ़ील्ड होने पर this.lockस्थानीय चर की प्रतिलिपि बनाने का कोई कारण है ?lockthis.lockfinal

इसके अतिरिक्त, यह उस E[]पर अभिनय करने से पहले एक स्थानीय प्रति का भी उपयोग करता है:

private E extract() {
    final E[] items = this.items;
    E x = items[takeIndex];
    items[takeIndex] = null;
    takeIndex = inc(takeIndex);
    --count;
    notFull.signal();
    return x;
}

क्या किसी अंतिम क्षेत्र को स्थानीय अंतिम चर में कॉपी करने का कोई कारण है?

जवाबों:


68

यह एक चरम अनुकूलन है डग ले, वर्ग के लेखक का उपयोग करना पसंद करता है। इस सटीक विषय के बारे में कोर-लिबास-डी मेलिंग सूची पर हाल ही में एक थ्रेड पर एक पोस्ट किया गया है जो आपके प्रश्न का बहुत अच्छा जवाब देता है।

पोस्ट से:

... स्थानीय लोगों की नकल करने से सबसे छोटा बायोटेक उत्पन्न होता है, और निम्न-स्तरीय कोड के लिए यह कोड लिखना अच्छा होता है जो मशीन के थोड़ा करीब होता है


15
"चरम" पर ज़ोर! यह एक सामान्य प्रयोजन की अच्छी प्रोग्रामिंग प्रथा नहीं है जिसका हर किसी को अनुकरण करना चाहिए।
केविन बोर्रिलिन

15
रैंडम FDI: कुछ अन्य मामलों में जब आप ऐसा करते हुए देखते हैं, यह इसलिए है क्योंकि विचाराधीन क्षेत्र अस्थिर है, और विधि को यह सुनिश्चित करने की आवश्यकता है कि इसे इसके लिए एक ही संगत मूल्य या संदर्भ मिल गया है।
केविन बोर्रिलिन

2
मैं इस तरह से एक कोर क्लास में "चरम" अनुकूलन ले जाऊंगा।
एरिक रॉबर्टसन

4
@zamza, स्थानीय अंतिम चर केवल जावा संकलक द्वारा उपयोग किया जाता है, नहीं बाईटकोड (यानी JVM अगर एक स्थानीय चर अंतिम है पता नहीं है)
bestsss

1
बाइटकोड आकार के अलावा, क्या यह निष्पादन गति के लिए भी एक अनुकूलन है?
शांतिबेल

13

यह धागा कुछ जवाब देता है। पदार्थ में:

  • संकलक आसानी से यह साबित नहीं कर सकता है कि अंतिम क्षेत्र एक विधि के भीतर नहीं बदलता है (प्रतिबिंब / क्रमांकन आदि के कारण)
  • अधिकांश वर्तमान संकलक वास्तव में कोशिश नहीं करते हैं और इसलिए अंतिम क्षेत्र को फिर से लोड करना होगा हर बार इसका उपयोग किया जाता है जिससे कैश मिस हो सकता है (पृष्ठ दोष)
  • इसे स्थानीय चर में संग्रहीत करने से जेवीएम केवल एक भार का प्रदर्शन करने के लिए मजबूर होता है

2
मुझे नहीं लगता finalकि JVM द्वारा किसी वैरिएबल को पुनः लोड किया जाना है। यदि आप finalप्रतिबिंब के माध्यम से एक चर को संशोधित करते हैं , तो आप सही ढंग से काम कर रहे अपने कार्यक्रम की गारंटी खो देते हैं (मतलब नए मूल्य को सभी मामलों में ध्यान में नहीं रखा जा सकता है)।
icza
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.