2012-05-24 11 views
5

मैं कुछ (उत्पादन!) में कोड भाग गया है कि नीचे स्निपेट ऐसा दिखता नियत:उस वस्तु के आधार पर एक तुल्यकालन ब्लॉक के भीतर एक वस्तु (जावा)

synchronized(some_object) { 
    some_object = new some_object() 
} 

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

उत्तर

2

फ्रांसिस कहता है, यह कोई समस्या नहीं हो सकती है। आपका स्निपेट इस के बराबर है:

SomeObject saved = some_object; 
synchronized(saved) { 
    some_object = new SomeObject() 
} 
+0

यह बिल्कुल इस तरह लिखा नहीं है। मेरे मामले में कक्षा में वैरिएबल some_object है जिसका उपयोग सिंक्रनाइज़ेशन ब्लॉक के लिए किया जाता है, और इस चर को उसी ब्लॉक में फिर से सौंप दिया जा रहा है। –

+0

+1 यहां कुंजी है कि सिंक्रनाइज़ेशन ऑब्जेक्ट को संदर्भित करता है, संदर्भ नहीं। 'नया' निष्पादित और असाइन करने के बाद, आप अभी भी पुराने ऑब्जेक्ट पर लॉक हैं। इस बिंदु पर नई वस्तु बंद नहीं है। जब सिंक्रनाइज़ किए गए ब्लॉक को पुराना ऑब्जेक्ट पर लॉक से बाहर कर दिया जाता है, और यदि इसका कोई अन्य संदर्भ मौजूद नहीं है तो यह जीसी के लिए योग्य है। यदि वास्तविक सिंक्रनाइज़ किए गए ब्लॉक में अधिक कोड है और यह लॉक पर किसी भी तरह से नई ऑब्जेक्ट को स्थानांतरित करने पर निर्भर करता है, तो आपको कोई समस्या हो सकती है। –

+1

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

4

यह वास्तव में ठीक हो सकता है कि क्या हो रहा है इसके आधार पर। आपको बड़े संदर्भ को समझने की आवश्यकता होगी। सिंक्रनाइज़ेशन उस ऑब्जेक्ट पर होगा जो ब्लॉक की शुरुआत में some_object द्वारा इंगित किया गया है। यह देखने के लिए कि यह एक बग है, आपके विवरण से पर्याप्त जानकारी नहीं है।

सिंक्रनाइज़ेशन स्वयं ठीक काम करेगा।

1

तुल्यकालन उद्देश्य यह है कि जब सिंक्रनाइज़ ब्लॉक में प्रवेश संदर्भित किया गया था पर है। सिंक्रनाइज़ किए गए ब्लॉक के अंदर किसी अन्य ऑब्जेक्ट के संदर्भ को इंगित करने से सिंक्रनाइज़ेशन बिल्कुल प्रभावित नहीं होता है। यह अभी भी "पुरानी" वस्तु पर सिंक्रनाइज़ है।

1

यह बहुत बुरा है। सिंक्रनाइज़ किया गया अंतिम श्रेणी के सदस्यों पर सबसे अच्छा उपयोग किया जाता है।

एक थ्रेड सुरक्षित तरीके से ऑब्जेक्ट बनाने का आधुनिक दृष्टिकोण एटमिक रिफरेंस तुलना और एक लूप में सेट करें जैसा कि गोएट्ज़ की जावा कंसुरेंसी इन एक्शन (चैप 15) में चर्चा की गई है। यह आपके धागे को अवरुद्ध नहीं करता है और एक सिंक्रनाइज़ ब्लॉक से कहीं अधिक प्रदर्शन प्रदान करता है।

private final AtomicReference<SomeObject> someObject = new AtomicReference<>(); 


void buildIt() { 
    SomeObject obj = new SomeObject(); 
    SomeObject current = someObject.get(); //probably null, but doesn't matter 
    while (true) { 
     if (someObject.compareAndSet(current, obj)) 
      break; 
    } 
} 
संबंधित मुद्दे