2011-08-13 14 views
36

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

सबसे पहले, यह unmentioned विधि थ्रेड-सुरक्षित है, और यदि हां, तो यह क्या सिंक्रनाइज़ करता है?

public class Singleton { 
    private Singleton instance; 

    private Singleton() { 
     //lots of initialization code 
    } 

    public static synchronized Singleton getInstance() { 
     if(instance == null) { 
      instance = new Singleton(); 
     } 
     return instance; 
    } 
} 

दूसरा, निम्नलिखित कार्यान्वयन थ्रेड सुरक्षित और प्रारंभिक में आलसी क्यों है? क्या होता है यदि दो धागे एक ही समय में getInstance() विधि दर्ज करते हैं?

public class Singleton { 
    private Singleton() { 
     //lots of initialization code 
    } 

    private static class SingletonHolder { 
     public static final Singleton instance = new Singleton(); 
    } 

    public static Singleton getInstance() { 
     return SingletonHolder.instance; 
    } 
} 

अंत में, दूसरे उदाहरण में, क्या एक थ्रेड पहले एक उदाहरण हो जाता है और एक और धागा एक उदाहरण हो जाता है और इससे पहले कि निर्माता पहले सूत्र में समाप्त हो गया है उस पर कार्रवाई करने के लिए कोशिश करता है तो क्या होगा? क्या आप तब एक असुरक्षित स्थिति में जा सकते हैं?

उत्तर

44

उत्तर 1: static synchronized विधियां क्लास ऑब्जेक्ट को लॉक के रूप में उपयोग करती हैं - यानी इस मामले में Singleton.class

उत्तर 2: जावा भाषा, अन्य बातों के अलावा:

  • भार वर्गों जब वे पहली बार एक्सेस किया जाता है/इस्तेमाल किया
  • गारंटी देता है कि एक वर्ग के लिए उपयोग की अनुमति दी है इससे पहले, सभी स्थिर initializers
  • पूरा कर लिया है

इन दो तथ्यों का अर्थ है कि आंतरिक स्थैतिक वर्ग SingletonHolder तब तक लोड नहीं होता है जब तक getInstance() विधि को कॉल नहीं किया जाता है। उस पल में, और थ्रेड बनाने से पहले कॉल को उस तक पहुंच प्रदान की जाती है, उस वर्ग का स्थिर उदाहरण क्लास लोडिंग के हिस्से के रूप में तत्काल होता है।

यह सब मतलब है कि हम बिना सुरक्षित आलसी लोड हो रहा है, और किसी भी तुल्यकालन/ताले के लिए की जरूरत!

यह पैटर्न पैटर्न है जो सिंगलेट के लिए उपयोग करने के लिए है। यह अन्य पैटर्न को धड़कता है क्योंकि MyClass.getInstance() सिंगलेट्स के लिए डिफैक्टो इंडस्ट्री मानक है - जो भी इसे उपयोग करता है स्वचालित रूप से जानता है कि वे एक सिंगलटन से निपट रहे हैं (कोड के साथ, यह हमेशा स्पष्ट होना अच्छा होता है), इसलिए इस पैटर्न में सही एपीआई और है हुड के तहत सही कार्यान्वयन।

बीटीडब्ल्यू Bill Pugh's article सिंगलटन पैटर्न को समझते समय पूर्णता के लिए पढ़ने योग्य है।

+0

उस लेख को पढ़ने के बाद, क्या मैं कह रहा हूं कि स्थिर स्थिर फ़ील्ड लोड करते समय जावा कुछ "आंतरिक" सिंक्रनाइज़ेशन करता है? – donnyton

+7

_ "यह पैटर्न सिंगलेट्स के लिए उपयोग करने का पैटर्न है।" _ - और [प्रभावी जावा के एनम सिंगलटन] के बारे में क्या है (http://stackoverflow.com/questions/427902/java-enum-singleton)? –

+3

एनम सिंगलटन आईएमएचओ इस के रूप में स्वच्छ या स्पष्ट नहीं है और इसलिए उतना अच्छा नहीं है: 'MyClass.getInstance() 'सिंगलेट्स के लिए उद्योग मानक है - जो भी इसे स्वचालित रूप से उपयोग करता है (चाहिए) जानता है कि वे इससे निपट रहे हैं एक सिंगलटन इस पैटर्न में सही एपीआई * और * हुड के नीचे सही कार्यान्वयन है। – Bohemian

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