10

यदि मैं किसी सिंक्रनाइज़ विधि या सिंक्रनाइज़ किए गए ब्लॉक के अंदर किसी ऑब्जेक्ट तक पहुंचता हूं, तो उस एक्सेस किए गए तत्व में सभी ऑब्जेक्ट भी सिंक्रनाइज़ किए जाते हैं?क्या जावा का सिंक्रनाइज़ेशन पूर्ण कैश अपडेट करेगा, या केवल उस ऑब्जेक्ट को सिंक्रनाइज़ किया जाएगा?

वहाँ एक वस्तु Queue एक तुल्यकालन add() और take() विधि है, को स्वीकार करने और बाहर सौंपने जटिल वस्तु Thing है कल्पना कीजिए। Thing में इसमें अन्य विभिन्न वस्तुओं के साथ कई सूचियां हैं।

अब छवि धागा BeforeThing बनाता है और Thing में कुछ मौजूदा वस्तुओं डालता है, इन वस्तु और इतने पर के कुछ संशोधित करता है। Before धागा ThingQueue जोड़ता है। थोड़ी देर बाद AfterQueue से Thing लेता है।

प्रश्न: Thing और उसके सभी बच्चे/सबोबजेक्ट Before के समान राज्य में होंगे? भले ही After धागा शायद कुछ उपखंडों में से एक पर काम कर रहा हो? क्योंकि मैं थ्रेड After के लिए प्रोसेसर को चित्रित करता हूं, फिर भी उस सबलेमेंट पर कुछ कैश की गई जानकारी हो सकती है (उस सबोबजेक्ट का पता अभी भी वही है)। सिंक्रनाइज़ तरीके से पिता ऑब्जेक्ट Thing तक पहुंचने के माध्यम से यह सभी कैश किए गए सामान को अमान्य कर दिया जाएगा?

कृपया समवर्ती libs आदि जैसे उत्तरों को उत्तर न दें। मैं समझना चाहता हूं कि क्या हो रहा है।

उत्तर

7

जावा के मेमोरी मॉडल में महत्वपूर्ण अवधारणा happens-before order है। लिखने वाले कार्यों के परिणाम पढ़ने से पहले इन पढ़ने के कार्यों को क्रियाएं दिखाई देती हैं। अन्य परिणाम दिखाई दे सकते हैं या नहीं भी हो सकते हैं।

होने से पहले आदेश प्राकृतिक व्यक्ति धागे में कार्रवाई के आदेश से धागे के बीच कार्यों का तुल्यकालन आदेश से प्रेरित है, और।

यदि आप Before किसी ऑब्जेक्ट पर सिंक्रनाइज़ करते हैं (उदा।अपने Queue), और कर Thing की अपनी जोड़तोड़ और अंदर या इस सिंक्रनाइज़-ब्लॉक से पहले अपने 'subobjects ", और After ही Queue पर सिंक्रनाइज़ के सभी और उन सभी परिवर्तनों में या सिंक्रनाइज़-ब्लॉक के बाद इन वस्तुओं पढ़ता है, तोAfter पर दिखाई दे रहे हैं।

9

एक धागा एक चर को संशोधित करता है, तो एक और धागा निम्नलिखित मामलों को छोड़कर परिवर्तन देखने के लिए गारंटी नहीं है (ठीक है, कम से कम निम्नलिखित मामलों में, अगर वहाँ अधिक कर रहे हैं मैं 100% यकीन नहीं है):

  • संशोधित धागा एक सिंक्रनाइज़ ब्लॉक या विधि छोड़ देता है; यह थ्रेड कैश की एक फ्लश उत्पन्न करता है (इसी तरह एक थ्रेड जो सिंक्रनाइज़ ब्लॉक में प्रवेश करता है या विधि रीफ्रेश को प्रेरित करता है) - यह आपके मामले में होता है
  • संशोधित चर घोषित किया गया है volatile या यह परमाणु चरों में से एक है java.util.concurrent.atomic
  • बदलाव धागा खत्म

तो अगर आप सिंक्रनाइज़ के रूप में आप बताया गया है, अन्य थ्रेड सभी परिवर्तन देखेंगे (यह भी एक फ्लश, वैसे ही एक धागे की शुरुआत एक ताज़ा लाती लाती है)।

+1

हाँ मुझे पता है, लेकिन यह मेरा सवाल नहीं था :-) सिंक्रनाइज़ेशन को प्रोसेसर कैश को भी प्रभावित करना चाहिए, ताकि परिवर्तन सामान्य स्मृति में फंस जाए, यही मेरा प्रश्न है। मुझे पता है कि यदि आप mulitple समानांतर धागे से सिंक्रनाइज़ किए गए ब्लॉक के बिना किसी संदर्भ का उपयोग करते हैं तो यह सब कुछ गड़बड़ हो जाता है। लेकिन यह एक थ्रेड से दूसरी थ्रेड में सामानों को पार करने और यह सुनिश्चित करने के बारे में अधिक है कि डेटास्ट्रूचर अभी भी सही है। मेरे कहे का मतलब समझो? –

+1

पाउलो द्वारा जवाब देखें। अवरुद्ध धागे सिंक्रनाइज़ेशन का केवल एक पहलू है, इससे पहले होता है कि रिश्ते (कैश को फ्लश करना) उतना ही महत्वपूर्ण है जितना अधिक नहीं। यह समझने के लिए भी बहुत मुश्किल है और एपीआई के बारे में अस्पष्ट नहीं है - उदाहरण के लिए, मुझे लगता है कि SwingUtilities.invokeLater पहले होता है, लेकिन मैं 100% निश्चित नहीं हूं)। मैं गोएट्ज़ एट अल से प्रैक्टिस में जावा कंसुरेंसी की दृढ़ता से अनुशंसा करता हूं। उन्होंने पहले-पर होने पर बहुत जोर दिया। – toto2

+0

स्पष्टीकरण के बिना डाउनवॉटिंग के लिए धन्यवाद ... @ फ्रांज: यह मेरे लिए स्पष्ट नहीं था कि आप मेमोरी मॉडल के बारे में पूछ रहे थे। मुझे अपने जवाब पर पुनर्विचार करने दो। – musiKk

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