2012-01-05 7 views
10

यह मेरे पिछले प्रश्न के उत्तराधिकारी, Is this variable being safely accessed by using synchronization?"सिंक्रनाइज़ (यह)" बनाम "सिंक्रनाइज़ ((बेस क्लास) यह)" जावा में?

निम्नलिखित कार्यक्रम के लिए,

Class SubClassB extends SuperClassA { 
    protected int c; 

    public void inc() { 
      synchronized (this) { 
       c++; 
      } 
    } 

    public void dec() { 
      synchronized ((SuperClassA) this) { 
       c--; 
      } 
    } 
} 

काउंटर "सी" धागा सुरक्षित पहुँचा जा चाहेंगे है? मुझे यकीन नहीं है कि "dec()" विधि में, SuperClassA कास्ट "यह" सिंक्रनाइज़ किए गए ब्लॉक के लिए एक वैध वस्तु संदर्भित करता है? यदि हां, तो क्या दो सिंक्रनाइज़ किए गए ब्लॉक समान "इस" ऑब्जेक्ट को लॉक करेंगे? (जैसा कि मुझे लगता है कि "(सुपरक्लासए) यह" बराबर नहीं है ")

यह अजीब सिमुलेट कोड निम्नलिखित वास्तविक जीवन उदाहरण से आता है जहां सुपर क्लास एक मूल श्रेणी है जिसे संशोधित नहीं किया जाना चाहिए,

Class SuperClassA { 
    protected int c; 

    public void dec() { 
      synchronized (this) { 
       c--; 
      } 
    } 
} 

Class SubClassB extends SuperClassA { 

    public void inc() { 
      synchronized (this) { 
       c++; 
      } 
    } 

    public void dec() { 
      super.dec(); 
    } 
} 

इस उदाहरण में, SubClassB में "दिसम्बर()" विधि अपने सुपर क्लास के "दिसम्बर()" विधि है जो एक "इस" उद्देश्य यह है कि मैं "SuperClassA.this" होने के लिए लगता है के लिए एक लॉक करता है कहता है। यदि SubClassB की "inc()" विधि में लॉक ऑब्जेक्ट ठीक से SubClassB की "dec()" विधि में लॉक ऑब्जेक्ट जैसा नहीं है, तो मुझे लगता है कि SubClassB में विरासत काउंटर "सी" को अलग-अलग धागे से सुरक्षित रूप से एक्सेस नहीं किया जा सकता है । मुझे लगता है कि सिंक्रनाइज़ ब्लॉक में "इस" संदर्भ का उपयोग करने में कुछ अस्पष्टताएं हैं।

वास्तविक जीवन उदाहरण में, यदि मैं चाहता हूँ SubClassB के काउंटर "सी" सुरक्षित थ्रेड किया जाना है,, मैं इस तरह अपने "दिसम्बर()" विधि में एक और सिंक्रनाइज़ ब्लॉक को जोड़ने के लिए, की जरूरत है

Class SubClassB extends SuperClassA { 

    public void inc() { 
      synchronized (this) { 
       c++; 
      } 
    } 

    public void dec() { 
      synchronized (this) { 
       super.dec(); 
      } 
    } 
} 

लेकिन ऐसा लगता है कि इस तरह के जोड़ा ब्लॉक सुरुचिपूर्ण नहीं है और अनावश्यक हो सकता है!

क्या किसी के पास इन सवालों पर कुछ विचार हैं। अग्रिम में धन्यवाद।

लॉरेंस

उत्तर

5

क्या काउंटर "सी" को थ्रेड सुरक्षित किया जाएगा?

हां, यह एक ही लॉक ऑब्जेक्ट का उपयोग कर रहा है।

मुझे यकीन नहीं है कि "dec()" विधि में, SuperClassA कास्ट "यह" सिंक्रनाइज़ किए गए ब्लॉक के लिए एक वैध वस्तु संदर्भित करता है?

हां।

यदि हां, तो क्या दो सिंक्रनाइज़ किए गए ब्लॉक समान "इस" ऑब्जेक्ट को लॉक करेंगे? (जैसा कि मुझे लगता है कि "(सुपर क्लासए) यह" बराबर नहीं है ")

हां। यहां तक ​​कि यदि आप किसी चीज़ को उदाहरण देते हैं तो इसे (ऑब्जेक्ट) तक भी जाया जा सकता है, फिर भी यह वही ऑब्जेक्ट देखेंगे।

[...] लेकिन ऐसा लगता है कि ऐसा जोड़ा गया ब्लॉक सुरुचिपूर्ण नहीं है और यह अनावश्यक हो सकता है!

यह अनावश्यक है। अतिरिक्त सिंक्रनाइज़ेशन केवल तभी जरूरी है जब आप एकाधिक सिंक्रनाइज़ किए गए तरीकों को कॉल करते हैं और संयुक्त प्रभाव परमाणु होना चाहिए।

+0

आपके उत्तरों के लिए धन्यवाद। – user1129812

2

सभी तीन उदाहरण जहाँ तक तुल्यकालन का संबंध है सही हैं।

  1. किसी ऑब्जेक्ट से जुड़े केवल एक मॉनिटर है।
  2. thissynchronized के अंदर बेस क्लास में कास्टिंग कोई फर्क नहीं पड़ता।
  3. एक ही वस्तु के लिए, इससे कोई फर्क नहीं पड़ता कि synchronized(this) व्युत्पन्न कक्षा या बेस क्लास के संदर्भ में लागू किया गया है: दोनों मामलों में एक ही लॉक का उपयोग किया जाता है।
+0

आपकी तेज प्रतिक्रिया के लिए धन्यवाद और मुझे याद दिलाता है कि किसी ऑब्जेक्ट के साथ केवल एक मॉनिटर है। – user1129812

6

कोड थ्रेड-सुरक्षित है, क्योंकि (SomeObject) this adn this एक ही ऑब्जेक्ट हैं। एक कास्ट किसी वस्तु को किसी अन्य वस्तु में परिवर्तित नहीं करता है।

कोड में encapsulation की कमी है, हालांकि, यह किसी भी subclass को असुरक्षित तरीके से संरक्षित c फ़ील्ड तक पहुंचने देता है। इसलिए, कोई सबक्लास किसी भी सिंक्रनाइज़ेशन के बिना c++ या c-- का उपयोग कर सकता है। क्षेत्र निजी होना चाहिए।

+0

मुझे याद दिलाने के लिए धन्यवाद कि काउंटर "सी" को "निजी" घोषित किया जाना चाहिए। – user1129812

3

मुझे लगता है कि "(SuperClassA) इस" से "इस"

गलत बराबर नहीं है; ऑब्जेक्ट्स पर सिंक्रनाइज़ेशन किया जाता है, और कास्टिंग केवल संकलन-समय प्रकार को बदलता है, इसका ऑब्जेक्ट पहचान पर कोई प्रभाव नहीं पड़ता है।

इस प्रकार, आपको उप-वर्ग में अतिरिक्त सिंक्रनाइज़ेशन जोड़ने की आवश्यकता नहीं है।

+0

अब मुझे पता है कि "(सुपर क्लासए) यह" और "यह" अलग संकलन-समय प्रकार के हैं लेकिन सिंक्रनाइज़ ब्लॉक में एक ही लॉक रखें। – user1129812