2012-10-31 8 views
74

मैंने समवर्ती हैश मैप के बारे में जेडीके के स्रोत कोड को पढ़ा।जेडीके स्रोतकोड 'अस्थिर' उदाहरणों की 'अंतिम' प्रतिलिपि क्यों लेता है

लेकिन निम्नलिखित कोड मुझे उलझन में:

public boolean isEmpty() { 
    final Segment<K,V>[] segments = this.segments; 
    ... 
} 

मेरा प्रश्न है:

"this.segments" घोषित किया जाता है:

final Segment<K,V>[] segments; 

तो, यहाँ, की शुरुआत में विधि, एक ही प्रकार के संदर्भ घोषित, एक ही स्मृति को इंगित करें।

लेखक ने ऐसा क्यों लिखा? उन्होंने इसका उपयोग क्यों नहीं किया। सेगमेंट सीधे? क्या कोई कारण है?

उत्तर

94

यह volatile चर शामिल लॉक-फ्री कोड के लिए एक मुहावरे सामान्य है। पहली पंक्ति में आप volatile एक बार पढ़ते हैं और फिर इसके साथ काम करते हैं। इस बीच एक और धागा volatile अपडेट कर सकता है, लेकिन आप केवल उस मूल्य में रुचि रखते हैं जिसे आपने प्रारंभ में पढ़ा था।

इसके अलावा, यहां तक ​​कि जब प्रश्न में सदस्य परिवर्तनीय अस्थिर लेकिन अंतिम नहीं है, तब भी इस मुहावरे को सीपीयू कैश के साथ करना होगा क्योंकि एक स्टैक स्थान से पढ़ने के रूप में एक यादृच्छिक ढेर स्थान से पढ़ने से अधिक कैश-अनुकूल है। एक उच्च संभावना भी है कि स्थानीय var एक सीपीयू रजिस्टर के लिए बाध्य हो जाएगा।

इस बाद के मामले में वास्तव में कुछ विवाद होता है, क्योंकि जेआईटी कंपाइलर आमतौर पर उन चिंताओं का ख्याल रखता है, लेकिन डौग ली उन लोगों में से एक है जो सामान्य सिद्धांत पर चिपकते हैं।

+0

तो अगर कोई 'इस। सेगमेंट' सामग्री को बदलता है, तो आप अपने 'सेगमेंट' में उस परिवर्तन को नहीं देख पाएंगे? – brimborium

+0

बेशक आप इसे देखेंगे। लेकिन अगर कोई 'सेगमेंट' के लिए कुछ और निर्दिष्ट करता है, तो आप निश्चित रूप से उस से अलग हो जाएंगे। –

+3

आह हाँ, यकीन है। अपने उत्तर को गलत समझाएं ...; – brimborium

19

मुझे लगता है कि यह प्रदर्शन विचार के लिए है, ताकि हमें केवल एक बार फ़ील्ड मान पुनर्प्राप्त करने की आवश्यकता हो।

आप यहोशू बलोच द्वारा प्रभावी जावा से एक सिंगलटन मुहावरा का उल्लेख कर सकते

उनकी सिंगलटन यहाँ है:

private volatile FieldType field; 
FieldType getField() { 
    FieldType result = field; 
    if (result == null) { 
    synchronized(this) { 
     result = field; 
     if (result == null) 
     field = result = computeFieldValue(); 
    } 
    } 
    return result; 
} 

और उन्होंने लिखा है:

इस कोड को एक सा दिखाई दे सकते हैं जटिल। विशेष रूप से, स्थानीय परिवर्तनीय परिणाम की आवश्यकता अस्पष्ट हो सकती है। यह चर क्या करता है यह सुनिश्चित करता है कि सामान्य मामले में फ़ील्ड केवल एक बार पढ़ा जाए जहां यह पहले ही प्रारंभ हो गया है। सख्ती से जरूरी नहीं है, यह प्रदर्शन में सुधार कर सकता है और निम्न स्तर समवर्ती प्रोग्रामिंग पर लागू मानकों से अधिक सुरुचिपूर्ण है। मेरी मशीन पर, उपरोक्त विधि स्थानीय चर के बिना स्पष्ट संस्करण की तुलना में लगभग 25 प्रतिशत तेज है।

+0

+1। –

4

यह बाइट कोड आकार को कम कर सकता है - एक स्थानीय चर का उपयोग करना एक आवृत्ति चर का उपयोग करने से बाइट कोड में छोटा है।

रनटाइम अनुकूलन ओवरहेड भी कम किया जा सकता है।

लेकिन इनमें से कोई भी महत्वपूर्ण नहीं है। यह कोड शैली के बारे में अधिक है। यदि आप सभी तरीकों से उदाहरण चर के साथ सहज महसूस करते हैं।डौग ली शायद स्थानीय चर के साथ अधिक आरामदायक व्यवहार महसूस करते हैं।

संबंधित मुद्दे