2013-08-21 9 views
32

सिंक्रनाइज़ेशन को देखने और समझने की कोशिश कर रहा है।सिंक्रनाइज़ ब्लॉक में स्थिर बनाम गैर स्थैतिक लॉक ऑब्जेक्ट

  1. एक स्थिर ताला वस्तु (कोड ए) और एक गैर स्थिर ताला वस्तु (कोड बी) का उपयोग कर के बीच मतभेद एक के लिए सिंक्रनाइज़ ब्लॉक क्या हैं?
  2. व्यावहारिक अनुप्रयोगों में यह अलग कैसे है?
  3. किसी के पास क्या नुकसान होगा जो दूसरे नहीं होगा?
  4. कौन सा उपयोग करने के लिए निर्धारित करने के लिए मानदंड क्या हैं?

कोड एक

public class MyClass1 { 
    private static final Object lock = new Object(); 
    public MyClass1() { 
    //unsync 
    synchronized(lock) { 
     //sync 
    } 
    //unsync 
    } 
} 

कोड बी

public class MyClass2 { 
    private final Object lock = new Object(); 
    public MyClass2() { 
    //unsync 
    synchronized(lock) { 
     //sync 
    } 
    //unsync 
    } 
} 

नोट

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

मैंने पहले ही this question में उत्तर देखा है, लेकिन यह स्पष्ट नहीं है कि विभिन्न उपयोग परिदृश्य क्या हैं।

+2

"ध्यान दें कि उपरोक्त कोड रचनाकारों को दिखाता है," यह एक महत्वपूर्ण भेद है। एक कन्स्ट्रक्टर पर एक इंस्टेंस फ़ील्ड वाला एक सिंक्रनाइज़ ब्लॉक बिल्कुल व्यर्थ है, क्योंकि एक ही उदाहरण पर कोई भी दो थ्रेड कभी कन्स्ट्रक्टर निष्पादित नहीं करेगा। – Thilo

+0

असल में, इसके बारे में सोचने के लिए आओ, उस उदाहरण फ़ील्ड में एक ऑब्जेक्ट हो सकता है जो धागे के बीच साझा किया जाता है। उदाहरण के लिए 'निजी अंतिम ऑब्जेक्ट लॉक = "niceLiteralString"; '। – Thilo

+0

मैं एक उदाहरण दिखाने के लिए रचनाकारों का उपयोग करके समझना एक बुरा विचार था। मेरा प्रश्न स्थिर और गैर स्थैतिक तरीकों तक भी विस्तारित है। साथ ही, स्थैतिक/उदाहरण फ़ील्ड को लॉकिंग को कैसे प्रभावित करता है? – ADTC

उत्तर

42

अंतर सरल है: अगर बंद कर दिया-ऑन वस्तु एक static क्षेत्र में है, तो वह ताला के MyClass*होगा शेयर सभी उदाहरणों (यानी कोई दो वस्तुओं एक ही समय में उस वस्तु पर लॉक करने के लिए सक्षम हो जाएगा) ।

यदि फ़ील्ड गैर-स्थैतिक है, तो प्रत्येक इंस्टेंस का अपना लॉक होगा, इसलिए उसी ऑब्जेक्ट पर विधि को केवल एक दूसरे को लॉक कर देगा।

आप एक स्थिर ताला वस्तु का उपयोग करते हैं:

  • धागा 1 कॉल o1.foo()
  • धागा 2 कॉल o1.foo(),,
  • 3 कॉल o2.foo() खत्म करने के लिए धागा धागा 1 के लिए प्रतीक्षा करनी होगी भी होगा को

को समाप्त करने के लिए थ्रेड 1 (और शायद 2) के लिए प्रतीक्षा करना होगा कहां एक गैर स्थिर ताला वस्तु का उपयोग करें:

  • धागा 1 कॉल o1.foo()
  • धागा 2 कॉल o1.foo(),
  • धागा 3 कॉल o2.foo() खत्म करने के लिए धागा 1 के लिए प्रतीक्षा करनी होगी, यह सिर्फ, जारी रख सकते हैं नहीं धागा 1 और 2

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

अंगूठे के नियम के रूप में, आप लॉक-ऑब्जेक्ट को ऑपरेटेड-ऑन मान की तुलना में static -ness रखना चाहते हैं। तो यदि आप गैर-स्थिर मान केवल में हेरफेर करते हैं, तो आप एक गैर स्थैतिक लॉक ऑब्जेक्ट चाहते हैं। यदि आप स्थिर मान केवल में हेरफेर करते हैं, तो आप एक स्थिर लॉक ऑब्जेक्ट चाहते हैं।

जब आप स्थैतिक और गैर स्थैतिक मानों का उपयोग करते हैं, तो यह जटिल हो जाएगा। आसान तरीका केवल स्थिर लॉक ऑब्जेक्ट का उपयोग करना होगा, लेकिन यह सिंक्रनाइज़-ब्लॉक के आकार को बिल्कुल जरूरी से अधिक बढ़ा सकता है और वांछित से अधिक विवाद को लॉक करने की आवश्यकता हो सकती है। उन मामलों में आपको स्थिर और गैर स्थैतिक लॉक ऑब्जेक्ट्स के संयोजन की आवश्यकता हो सकती है।

अपने विशेष मामले में आप कन्स्ट्रक्टर में लॉक का उपयोग करते हैं, जिसे केवल प्रति उदाहरण एक बार निष्पादित किया जाएगा, इसलिए एक गैर स्थैतिक लॉक-ऑब्जेक्ट यहां कोई समझ नहीं लेता है।

+1

मुझे लगता है कि एक उदाहरण के रूप में निर्माता का उपयोग करना एक बुरा विचार था। वैसे भी, अच्छा जवाब। मैं एक और सवाल पूछना चाहता हूं।क्या यह सुनिश्चित करने का एक तरीका है कि एक थ्रेड के माध्यम से एक ** अस्थिर स्थिर ** सदस्य चर पर चलने वाले तरीकों का एक सेट _done और over_ से अधिक होगा, अन्य धागे इस सदस्य चर को एक्सेस करने से पहले? अगर आवश्यक हो तो मैं एसओ पर एक अलग सवाल कर सकता हूं। – ADTC

+0

@ADTC: यह मेरे लिए एक अलग प्रश्न की तरह लगता है। संक्षिप्त उत्तर: नहीं, आपको सिंक्रनाइज़ेशन की आवश्यकता होगी। आप केवल तभी बच सकते हैं जब अस्थिरता का संचालन * परमाणु * (उदाहरण के लिए 'int' ** पर ** एकल '++' और ** आपको ऑर्डर की परवाह नहीं है (यानी आप परवाह नहीं है आप ऑपरेशन से पहले या बाद में पढ़ते हैं) –

+0

मुझे पढ़ने के बारे में परवाह है, इसे ऑपरेशन के बाद ही होना चाहिए। मुझे लगता है कि मैं इसे एक अलग प्रश्न के रूप में पूछूंगा। – ADTC

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