2012-04-17 20 views
20

शून्य पर सेट JVM पहले thread1 कार्यान्वित और अशक्त करने के लिए obj1 सेट अगर मैं दो धागे Thread1 और Thread2सिंक्रनाइज़ वस्तु

//Within Thread1  
synchronized(obj1) 
{ 
    obj1 = null; 
} 

//Within Thread2 
synchronized(obj1) 
{ 
    do something 
} 

है, तो thread2 होगा कि परिवर्तन तुरंत देख सकते हैं या यह समय लगेगा और JVM अभी भी चला सकते हैं थ्रेड 2 सिंक्रनाइज़ ब्लॉक क्योंकि obj1 अभी तक शून्य नहीं है?

+7

@ KorhanÖztürk वह खुद को आजमा नहीं सकता था, किसी भी प्रकार की सहमति से संबंधित मुद्दा गैर निर्धारक नहीं है। जब संदर्भ ज्ञात नहीं है तो इस प्रकार की टिप्पणियां बेहद निराशाजनक होती हैं। –

उत्तर

28

यह लगभग निश्चित रूप से सिंक्रनाइज़ेशन अबास्ट्रक्शन को तोड़ देगा - मुझे विश्वास नहीं होगा कि thread2 तुरंत परिवर्तन देखेंगे। आपको उस ऑब्जेक्ट का संदर्भ कभी भी नहीं बदलना चाहिए जिस पर आप सिंक्रनाइज़ कर रहे हैं, इसे null पर बहुत कम सेट करें, जिससे NullPointerException पर सिंक्रनाइज़ करने के किसी और प्रयास पर इसका कारण बन जाएगा।

9

सबसे पहले मुझे जोर दें कि सिंक्रनाइज़ेशन के लिए उपयोग किए जाने वाले चर को संशोधित करना बहुत खराब बात ™ है। obj1final होना चाहिए और यदि इसे मॉनिटर के रूप में उपयोग किया जाता है तो कभी भी स्पर्श नहीं किया जाना चाहिए।

कहा जा रहा है, वापस अपने प्रश्न का:

JVM पहले Thread1 निष्पादित करता है, यह obj1 पर सिंक्रनाइज़ करता है, null और धागा बाहर निकलता है के लिए यह तय करता है। दूसरा धागा obj1, NullPointerException पर सिंक्रनाइज़ करना चाहता है। चूंकि obj1 का संशोधन सिंक्रनाइज़ किए गए ब्लॉक में किया गया था, इसलिए यह गारंटी दी जाती है कि थ्रेड 2 अपडेट किए गए मान को देखेगा (इसलिए: NullPointerException की गारंटी है)।

Thread1 obj1 पर ताला प्राप्त करने के बाद, लेकिन संदर्भ साफ़ करने से पहले बाधित हो जाए, Thread2 obj1 पर ताला और जब तक प्रतीक्षा करें Thread1 समाप्त हो जाएगा। फिर यह सफलतापूर्वक मॉनीटर में प्रवेश करेगा क्योंकि पहले obj1 द्वारा संदर्भित ऑब्जेक्ट अभी भी मौजूद है।

+0

चूंकि obj1 सिंक्रनाइज़ स्थिति में उपयोग किया जा रहा है, सिंक्रनाइज़ किए गए ब्लॉक में नहीं, यह संभव नहीं है कि दोनों थ्रेड एक ही समय में सिंक्रनाइज़ करने का प्रयास करें और थ्रेड 1 पहले प्रवेश करता है और thread2 obj1 के मान को कैश करता है।जब थ्रेड 1 थ्रेड 2 से बाहर निकलता है तो कैश से obj1 का मान लेता है और सिंक्रनाइज़ ब्लॉक में प्रवेश करता है और सिंक्रनाइज़ किए गए ब्लॉक – vjk

+0

@Tomsaz के भीतर परिवर्तन को देखता है मुझे आपके इस कथन को नहीं मिला _ अगर थ्रेड 1 obj1 पर लॉक प्राप्त करने के बाद बाधित है लेकिन साफ़ करने से पहले संदर्भ, थ्रेड 2 ओबीजे 1 पर लॉक होगा और थ्रेड 1 समाप्त होने तक प्रतीक्षा करें। अब सबसे पहले हम अवरुद्ध होने पर थ्रेड को बाधित करते हैं और फिर भी अगर वे अवरुद्ध नहीं होते हैं तो उन्हें कोई प्रभाव नहीं पड़ता है, है ना? असल में मैं कभी ऐसा मामला नहीं देखता जहां थ्रेड 1 सिंक्रनाइज़ किए गए ब्लॉक को पूरा किए बिना लॉक को छोड़ देगा या बिना लॉक के कॉल() को कॉल किया जा रहा है। IOW, कब और क्यों थ्रेड 2 लॉक प्राप्त करेंगे, लेकिन अभी भी थ्रेड 1 को समाप्त करने की प्रतीक्षा करेंगे। – sactiw

4

synchronized ऑब्जेक्ट पर सिंक्रनाइज़ करता है, न कि संदर्भ। obj1 (एक संदर्भ) को शून्य पर सेट करके, थ्रेड 2 उस ऑब्जेक्ट पर सिंक्रनाइज़ नहीं कर सकता है जिसे पहले obj1 पर इंगित किया गया था, आपको इसके बजाय NullPointerException मिलेगा।

0

परिवर्तन तत्काल है। जब थ्रेड 1 लॉक का मालिक होता है, तो यह इच्छा पर obj1 के मान को बदल सकता है। थ्रेड 2 को प्रतीक्षा करना है जब तक कि थ्रेड 1 लॉक जारी नहीं करता है। यह निश्चित रूप से

वस्तु [] obj1 = {} अशक्त obj1 देखेंगे == बातिल

1

एक त्वरित सुधार वस्तु 1 तत्व का एक सरल सरणी बनाने के लिए और तुल्यकालन के लिए सरणी, उदा का उल्लेख करने के लिए है,;

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

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