पहले, सिंक्रनाइज़ तरीकों के बारे में भूल जाते हैं। एक तथाकथित समन्वयित विधि ...
synchronized AnyType foobar(...) {
doSomething();
}
लेकिन इस लेखन के लिए एक शॉर्टकट रास्ता कुछ भी नहीं है:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
या तो मामले में विधि के बारे में विशेष कुछ भी नहीं है। क्या खास है सिंक्रनाइज़ ब्लॉक है, और क्या एक तुल्यकालन ब्लॉक करता है बहुत सरल है। जब JVM इस कार्यान्वित:
synchronized(foo) {
doSomething();
}
यह पहली बार अभिव्यक्ति foo
मूल्यांकन करता है। परिणाम एक ऑब्जेक्ट संदर्भ होना चाहिए। फिर यह ऑब्जेक्ट लॉक करता है, synchronized
ब्लॉक का शरीर निष्पादित करता है, और फिर यह ऑब्जेक्ट को अनलॉक करता है।
लेकिन क्या लॉक किया मतलब है? इसका मतलब आपके विचार से कम हो सकता है। यह ऑब्जेक्ट का उपयोग करने से अन्य धागे को रोकता है।यह उन्हें ऑब्जेक्ट के फ़ील्ड तक पहुंचने से या अपने फ़ील्ड को अपडेट करने से नहीं रोकता है। एक वस्तु को लॉक करने वाली एकमात्र चीज रोकती है, यह अन्य धागे को एक ही ऑब्जेक्ट को एक ही समय में लॉक करने से रोकती है।
धागा कुछ समय धागा पहले से ही foo बंद कर दिया गया है (उसी synchronized
ब्लॉक में, या एक अलग से एक में) synchronized(foo) {...}
दर्ज करने के लिए, तो थ्रेड धागा रिलीज ताला तक इंतजार करने के लिए मजबूर हो जाएगा की कोशिश करता है।
आप synchronized
ब्लॉक का उपयोग डेटा की रक्षा के लिए।
मान लीजिए कि आपके प्रोग्राम में ऑब्जेक्ट्स का कुछ संग्रह है जो अलग-अलग राज्य में हो सकता है। मान लीजिए कि कुछ राज्य समझ में आते हैं, लेकिन ऐसे अन्य राज्य हैं जो समझ में नहीं आते- अमान्य राज्य।
मान लीजिए कि किसी थ्रेड के लिए किसी वैध स्थिति से डेटा को अस्थायी रूप से अमान्य स्थिति बनाने के बिना किसी वैध स्थिति से डेटा को बदलने के लिए संभव नहीं है।
आप कोड है कि एक synchronized(foo)
ब्लॉक में राज्य में परिवर्तन कर दिया है, और आप कोड के हर ब्लॉक कि राज्य देख सकते हैं एक तुल्यकालन ब्लॉक कि एक ही वस्तु, foo
ताले में तो आप शब्दों में कहें, तो अस्थायी अमान्य स्थिति को देखने से अन्य धागे को रोक देगा।
आपकी व्याख्या बहुत अच्छी और समझने में आसान है। चूंकि आप अधिक विस्तार से गए हैं, मुझे पूछना चाहिए ... अनलॉक के लिए अन्य धागे को निलंबित (प्रतीक्षा) कहां दिया जाएगा, जब कोई थ्रेड ऑब्जेक्ट को लॉक करता है? मुझे इसकी शायद 'डिबगिंग' सवाल पता है, लेकिन जब मैंने अपने डेडलॉक के दौरान सभी धागे को निलंबित कर दिया तो मैं उलझन में था, क्योंकि मुझे दो सिग्नल दोनों सिंक्रनाइज़ किए गए विधि को निष्पादित करते थे - मैं शुरुआत में एक की अपेक्षा करता हूं और एक दूसरे सिंक्रनाइज़ की शुरुआत में इंतजार करता है विधि (लूप बनाने के लिए)। – arenaq
@arenaq _Where?_ डीबगर आपको क्या दिखाएगा? मुझे नहीं पता। मैंने डिबगर्स में ज्यादा जावा कोड नहीं देखा है। मैं एक सी प्रोग्रामर हूँ। सिंक्रनाइज़ेशन सी में एक आंतरिक भाषा सुविधा नहीं है, इसलिए सी में, डीबगर दिखाता है कि थ्रेड को सिंक्रनाइज़ेशन सिस्टम कॉल में बंद कर दिया गया है, कॉल के अंदर से सिंक्रनाइज़ेशन लाइब्रेरी फ़ंक्शन में, मेरे कोड में कहीं से। जावा डिबगर्स जो मैंने उपयोग किया है, वे सिस्टम कॉल या जेवीएम की आंतरिक कार्यप्रणाली नहीं दिखाते हैं, और मुझे कभी भी जावा थ्रेड के ढेर का निरीक्षण नहीं करना पड़ता है जो लॉक प्राप्त करने का इंतजार कर रहा था। –
इसे भूल जाओ, इसके असंबद्ध प्रश्न वैसे भी ... एक नया विषय होना चाहिए। – arenaq