2012-02-17 9 views
25

एक कक्षा में मैं एक ConcurrentHashMap उदाहरण है कि संशोधित और पढ़ा जाएगा एक से अधिक थ्रेड से है, तो मैं इस तरह से परिभाषित करें:ऑब्जेक्ट सदस्य परिवर्तक जावा में अंतिम और अस्थिर दोनों क्यों नहीं हो सकता है?

public class My Class { 

    private volatile ConcurrentHashMap<String,String> myMap = new ConcurrentHashMap<String,String>(); 
... 
} 

एक त्रुटि में myMap क्षेत्र परिणाम के लिए final जोड़ने कह मैं केवल अंतिम उपयोग कर सकते हैं या अस्थिर। यह दोनों क्यों नहीं हो सकता है?

+0

कुछ हद तक संबंधित http://stackoverflow.com/questions/2964206/java-concurrency-volatile-vs-final-in-cascaded-variables – Jayan

उत्तर

23

volatile केवल वैरिएबल के संशोधनों के लिए प्रासंगिकता है, न कि उस वस्तु को संदर्भित करता है। final volatile फ़ील्ड होने का कोई मतलब नहीं है क्योंकि अंतिम फ़ील्ड को संशोधित नहीं किया जा सकता है। बस final फ़ील्ड घोषित करें और यह ठीक होना चाहिए।

+0

बस अपनी टिप्पणी स्पष्ट करने के लिए कि "अंतिम क्षेत्रों को संशोधित नहीं किया जा सकता"; अंतिम क्षेत्र वास्तव में, परिवर्तनीय हैं, लेकिन अंतिम कीवर्ड केवल एक बार असाइनमेंट करने की अनुमति देता है। – johntrepreneur

+3

@johnterpreneur: यह सही नहीं है; अंतिम फ़ील्ड * ऑब्जेक्ट * के निर्माण के दौरान ही असाइन किए जा सकते हैं, जो कि "अपरिवर्तनीय" की परिभाषा है। –

+0

यदि कीवर्ड 'फाइनल' के उपयोग से आपके द्वारा बताए गए ऑब्जेक्ट्स अपरिवर्तनीय बनाते हैं, तो 'स्ट्रिंगबिल्डर' सदस्य परिवर्तनीय फ़ाइनल घोषित करने से आप इसे संशोधित करने की अनुमति नहीं देंगे। हालांकि आप इसे संशोधित कर सकते हैं और ऑब्जेक्ट को बदलने के लिए '.append' को कॉल कर सकते हैं। – johntrepreneur

2

volatile चर है कि उनके मूल्य कुछ मामलों में, बदल सकता है के लिए प्रयोग किया जाता है, अन्यथा volatile के लिए कोई जरूरत नहीं है, और final मतलब यह है कि चर को बदल नहीं सकता है, तो volatile के लिए कोई आवश्यकता नहीं है।

आपका संगामिति चिंताओं महत्वपूर्ण हैं, लेकिन HashMapअस्थिर समस्या का समाधान नहीं होगा, संगामिति मुद्दों से निपटने के लिए है, तो आप पहले से ही उपयोग ConcurrentHashMap बना रही है।

+0

आप हैश मैप (या कोई अन्य ऑब्जेक्ट) 'अस्थिर' नहीं बना सकते हैं। 'अस्थिर' कीवर्ड वेरिएबल को प्रभावित करता है, न कि वे ऑब्जेक्ट्स जिन्हें वेरिएबल संदर्भित कर सकते हैं। –

7

क्योंकि volatile और final जावा में दो चरम समाप्त हो जाता

volatile मतलब है चर परिवर्तन के लिए बाध्य है

final मतलब है चर के मूल्य जो भी

1

कभी नहीं बदलेगा क्योंकि यदि ऐसा नहीं होता इसका कोई मतलब है। अस्थिर वस्तु ऑब्जेक्ट संदर्भ मान को प्रभावित करता है, ऑब्जेक्ट के फ़ील्ड/आदि नहीं।

आपकी स्थिति में (आपके समवर्ती मानचित्र हैं) आपको क्षेत्र final करना चाहिए।

1

volatile संशोधक गारंटी देता है कि सभी पढ़ते हैं और लिखते हैं मुख्य स्मृति में स्ट्रेट जाते हैं, यानी परिवर्तनीय पहुंच लगभग synchronized ब्लॉक में है। यह अंतिम चर के लिए अप्रासंगिक है जिसे बदला नहीं जा सकता है।

21

यह जावा मेमोरी मॉडल (जेएमएम) की वजह से है।

अनिवार्य रूप से, जब आप ऑब्जेक्ट फ़ील्ड को final के रूप में घोषित करते हैं तो आपको इसे ऑब्जेक्ट के कन्स्ट्रक्टर में प्रारंभ करना होगा और फिर final फ़ील्ड इसके मान को नहीं बदलेगा। और जेएमएम ने वादा किया है कि सीटीआर समाप्त होने के बाद कोई भी थ्रेड final फ़ील्ड के समान (सही) मान को देखेगा। इसलिए, final फ़ील्ड के सभी मानों को सही मान देखने की अनुमति देने के लिए आपको synchronize या Lock जैसे स्पष्ट सिंक्रनाइज़ेशन का उपयोग करने की आवश्यकता नहीं होगी।

जब आप ऑब्जेक्ट के क्षेत्र को volatile के रूप में घोषित करते हैं, तो फ़ील्ड का मान बदल सकता है, लेकिन फिर भी किसी भी थ्रेड से मूल्य के प्रत्येक पढ़ने को इसके लिए नवीनतम मूल्य दिखाई देगा।

तो, final और volatile ही उद्देश्य को प्राप्त - वस्तु के क्षेत्र मूल्य की दृश्यता, लेकिन पहले विशेष रूप से एक चर के लिए प्रयोग किया जाता है केवल एक बार करने के लिए सौंपा जा सकता है और दूसरा एक चर कई बार बदला जा सकता है कि के लिए प्रयोग किया जाता है।

संदर्भ:

+0

के लिए भी दृश्यमान नहीं है। स्पष्टीकरण मेरे लिए काफी अच्छा है, हालांकि मैं यह नहीं कहूंगा कि अंतिम 'स्थिर' मानों के लिए अंतिम उपयोग किया जाता है। यह कथन थोड़ा भ्रामक है, हालांकि मैं समझता हूं कि आप क्या कहना चाहते थे। –

+1

'"अंतिम और अस्थिर" एक ही उद्देश्य प्राप्त करते हैं ...' मुझे लगता है कि घोड़े के सामने गाड़ी डाल रहा है। 'अंतिम' का _purpose_ घोषित करना है कि एक चर या फ़ील्ड असाइन नहीं किया जाना चाहिए। 'अस्थिर' का _purpose_ संकलक को बताना है कि कोड की जांच करके मूल्य का अनुमान नहीं लगाया जा सकता है। तथ्य यह है कि जावा मेमोरी मॉडल में उन दो प्रकार के चर के प्रत्येक दृश्यता के बारे में विशेष नियम हैं, जो उनके गैर-ओवरलैपिंग उद्देश्यों के लिए माध्यमिक हैं। –

4

एक volatile क्षेत्र आप क्या होता है जब आप इसे बदल के रूप में की गारंटी देता है देता है। (कोई एक वस्तु जो इसे एक के संदर्भ में हो सकता है)

एक final क्षेत्र बदला नहीं जा सकता (क्या क्षेत्रों का संदर्भ बदला जा सकता है)

यह कोई मतलब नहीं है दोनों के लिए।

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