2012-06-23 11 views
6

संभव डुप्लिकेट:
Avoid synchronized(this) in Java?जावा में "इस" या निजी ऑब्जेक्ट पर सिंक्रनाइज़ेशन?

कोड के दो टुकड़ों के बीच क्या अंतर है? प्रत्येक के फायदे और नुकसान क्या हैं?

1)

public class Example { 
private int value = 0; 

public int getNextValue() { 
    synchronized (this) { 
     return value++; 
    } 
} 
} 

2)

public class Example { 
private int value = 0; 

private final Object lock = new Object(); 

public int getNextValue() { 
    synchronized (lock) { 
     return value++; 
    } 
} 
} 
+2

का उल्लेख करता है, दूसरा दृष्टिकोण लगभग हमेशा बेहतर होता है (AFAIK) - लेकिन क्यों? 'इस' की दृश्यता (केवल "ऑब्जेक्ट" से बाहर) की नकारात्मक प्रभाव क्या है? सिंक्रनाइज़ेशन लक्ष्य के साथ "खराब कोड" हस्तक्षेप कैसे कर सकता है? –

+0

क्या आप जानते हैं कि 'pubilc सिंक्रनाइज़ int intNextValue() {...} 'बिल्कुल' public int getNextValue() {सिंक्रनाइज़ (यह) {...}}' जैसा ही है? – Miquel

उत्तर

3

मुख्य कारण मैं 2 दृष्टिकोण का चयन होता है कि मैं ग्राहकों को क्या मेरी कक्षा के उदाहरण के साथ क्या नियंत्रण नहीं है। ,

class ClientCode { 
    Example exampleInstance; 

    void someMethod() { 
     synchronized (exampleInstance) { 
      //... 
     } 
    } 
} 

अगर मेरे Example वर्ग के भीतर, मैं:

हैं, तो किसी कारण से, किसी को एक ताला के रूप में मेरी कक्षा का एक उदाहरण का उपयोग करने का फैसला करता है, वे मेरी कक्षा के भीतर तुल्यकालन तर्क के साथ हस्तक्षेप करेगा मैं एक ताला का उपयोग कर रहा हूं कि कोई और नहीं देख सकता है, वे मेरे तर्क में हस्तक्षेप नहीं कर सकते हैं और उपरोक्त परिदृश्य में मनमाने ढंग से म्यूटेक्स पेश कर सकते हैं।

समेकित करने के लिए, यह केवल जानकारी छिपाने के सिद्धांत का एक आवेदन है।

0

मैं कहूंगा कि दूसरी विधि बेहतर है। निम्नलिखित स्थिति पर विचार करें:

public class Abc{ 

    private int someVariable; 

    public class Xyz { 
     //some method,synchronize on this 
    } 

     //some method, and again synchronize on this 


} 

इस स्थिति this में दो तरीकों में समान नहीं है। एक आंतरिक वर्ग की एक विधि है। इसलिए, सिंक्रनाइज़ेशन के लिए एक सामान्य वस्तु का उपयोग करना बेहतर है। उदा।, synchronized (someVariable)

+0

हालांकि, आप सिंक्रनाइज़ (Abc.this) 'का उपयोग कर सकते हैं। – Thilo

+0

यूप। यह भी विकल्प है, लेकिन सवाल 'इस', यानी वर्तमान 'ऑब्जेक्ट' के संदर्भ के बारे में है। हालांकि, मैं अभी भी एक शुरुआत कर सकता हूं। :-) –

+1

प्रैक्टिस बुक में जावा कंसुरेंसी में यह बग था। –

3

यदि मुझे एक साथ दो अलग-अलग कार्यों को एक दूसरे से स्वतंत्र करने की आवश्यकता है तो मैं दूसरा विकल्प पसंद करूंगा।

उदा .:

public class Example { 
    private int value = 0; 
    private int new_value = 0; 
    private final Object lock1 = new Object(); 
    private final Object lock2 = new Object(); 

    public int getNextValue() { 
     synchronized (lock1) { 
      return value++; 
     } 
    } 

    public int getNextNewValue() { 
     synchronized (lock2) {    
      return new_value++; 
     } 
    } 
} 
0

मुझे लगता है कि यह वास्तव में स्थिति पर निर्भर करता है। मान लें कि आपकी कक्षा एक उप-वर्ग है और सुपर क्लास में एक विधि है जिसमें सिंक्रनाइज़ेशन है। और मान लें कि आप एक ही डेटा सेट के साथ काम कर रहे हैं और अपनी विधि के भीतर भी अखंडता बनाए रखना चाहते हैं। फिर निश्चित रूप से 1 दृष्टिकोण है जो आपको उपयोग करना चाहिए।

अन्यथा दूसरा दृष्टिकोण किस प्रकार कास्टी

+0

मैं आपसे सहमत हूं लेकिन इस मामले में मैं कहूंगा कि सुपरक्लास बिल्कुल सही ढंग से डिज़ाइन नहीं किया गया है; यह एक 'संरक्षित' लॉक प्रदान कर सकता है जिसे मैं पूरे सिंक्रनाइज़ेशन तर्क को सार्वजनिक रूप से उपलब्ध कराए बिना सबक्लास में उपयोग कर सकता हूं। –

+1

@CostiCiudatu पूरी तरह से उस पर सहमत हैं। यह केवल उन मामलों में है जहां आप किसी और के कोडबेस से कुछ कक्षाएं प्राप्त करते हैं। यह शायद दुर्लभ है। अच्छी गुणवत्ता कटाक्ष के लिए – Vidyanand

+0

+1 - 'यह शायद दुर्लभ है :) :)। मेरा मुद्दा केवल इस बात पर जोर देना था कि जब आप चुनने में सक्षम होते हैं, तो यह दृष्टिकोण * अनुशंसित नहीं है, लेकिन कुछ परिदृश्यों में केवल एकमात्र उपलब्ध तरीका है। –