2012-12-05 16 views
9

2 विकल्प हैं? (Singlethreaded या बहु-क्रम)सिंगलटन और जनता स्थिर चर जावा

अपडेट: मैं बिल प्यूघ या enum विधि के बारे में पता कर रहा हूँ। मैं सही तरीके से नहीं ढूंढ रहा हूं, लेकिन मैंने केवल उपयोग किया है 1. क्या वास्तव में कोई अंतर बी/डब्ल्यू 1 या 2 है?

+0

आपके अपडेट किए गए प्रश्न के बाद कोई अंतर नहीं। –

+1

यह सवाल सिंगलटन के साथ कुछ भी नहीं है। आप सिंक्रनाइज़/गैर-सिंक्रनाइज़ संदर्भ से स्थिर फ़ील्ड तक पहुंचने के बारे में पूछते हैं। कृपया टैग संपादित करें। – Juvanis

+0

@ भविक अंबानी मैं असहमत हूं क्योंकि पहला विकल्प प्रत्येक थ्रेड को लॉक करेगा जो उदाहरण प्राप्त करने का प्रयास करता है और इसलिए थोड़ा कम प्रदर्शन करता है। –

उत्तर

10

मुख्य अंतर यह है कि पहले विकल्प के साथ, सिंगलटन केवल तब शुरू किया जाएगा जब getInstance कहा जाता है, जबकि दूसरे विकल्प के साथ, जैसे ही युक्त श्रेणी लोड हो जाती है, इसे प्रारंभ किया जाएगा।

public enum Singleton { 
    INSTANCE; 
} 
+0

के लिए अन्य बेहतर तरीके से पोस्ट किया है, मेरी गलती, किसी भी तरह से इसे याद किया। अब सवाल अपडेट कर लिया है। इसके अलावा, मुझे ENUM सिंगलटन इंस्टेंस के बारे में पता है, बस 2 बी अंतर को जानना चाहता था, लेकिन वैसे भी धन्यवाद! – Achow

2

वहाँ एक अंतर है::

समाधान 1 एक आलसी आरंभीकरण है, सिंगलटन उदाहरण हो जाएगा

एक तिहाई (पसंदीदा) विकल्प जो आलसी है और सुरक्षित थ्रेड एक enum उपयोग करने के लिए है की getInstance

समाधान 2 पहले आह्वान पर एक उत्सुक आरंभीकरण है बनाया है, सिंगलटन उदाहरण बनाने जाएगा जब वर्ग loades

वे दोनों थ्रेड सुरक्षित हैं, दूसरी एक बहु थ्रेडिंग को थोड़ा भ्रामक है

+1

ठीक है, मैंने बहु-थ्रेडेड बिट में नहीं डाला था। इसे संपादित किया गया था ..: पी – Achow

1

तो, अद्यतन के साथ दोनों विकल्प थ्रेड-सुरक्षित हैं। हालांकि synchronized विकल्प को प्रत्येक थ्रेड की आवश्यकता होती है जो इस लॉक को प्राप्त करने के लिए instance पर कॉल करता है जिससे प्रदर्शन कम हो जाता है यदि यह बहुत कुछ किया जाता है। इसके अलावा, विधि स्तर पर synchronized का उपयोग सार्वजनिक रूप से उपलब्ध लॉक (कक्षा स्वयं) का उपयोग करने का संभावित मुद्दा है, इसलिए यदि कुछ थ्रेड इस लॉक को प्राप्त करता है (जो यह हो सकता है) तो आप डेडलॉक के साथ समाप्त हो सकते हैं। static final विकल्प अधिक प्रदर्शन करने वाला है लेकिन सिंगलटन का आलसी प्रारंभ नहीं करता है (जो सिस्टम के आधार पर कोई समस्या नहीं हो सकती है)।

एक अन्य विकल्प है कि धागे की सुरक्षित सिंगलटन की init आलसी की अनुमति देता है इस प्रकार है:

public class MySingleton{ 
     private static class Builder{ 
      private static final MySingleton instance = new MySingleton(); 
     } 

     public static MySingleton instance(){ 
      return Builder.intance; 
     } 
} 

यह काम करता है क्योंकि स्थिर भीतरी कक्षा से पहले युक्त कक्षा में किसी भी विधि के निष्पादित होने प्रारंभ करने के लिए guarenteed है। जावा में

+0

-1 मतदाता, तर्क को स्पष्ट करने की देखभाल? –

+0

मैंने अभी जवाब को दोबारा पढ़ा है, और इसमें समस्या नहीं है जो मैंने सोचा था। उसके लिए क्षमा चाहता हूँ। :) मेरे -1 हटा दिया। जवाब मुझे शब्द सलाद की तरह थोड़ा दिखता है, हालांकि ... और वास्तविक अंतर पर आंशिक रूप से छूता है (आलसी बनाम प्रारंभिक शुरुआत)। आप प्रदर्शन और लॉकिंग का उल्लेख करते हैं, लेकिन वे मुख्य अंतर नहीं हैं। – cHao

-1

सिंगलटन कार्यान्वयन (यदि आप वास्तव में चाहते हैं) एक और अधिक सुरुचिपूर्ण ढंग से किया जा सकता है की तुलना में आप दोनों के लिए उत्सुक और आलसी आरंभीकरण के लिए का वर्णन किया। जोशुआ ब्लोच और the SingletonHolder solution द्वारा क्रमशः बिल पुग द्वारा प्रस्तावित the enum way देखें।

विकिपीडिया लेख में यह भी पैटर्न समझने के लिए एक अच्छी शुरुआत है और अपने प्रश्न का उत्तर है।

+1

प्रश्न का उत्तर नहीं देता है। यदि आप एक बेहतर तरीका सुझाना चाहते हैं, तो यह ठीक है ... लेकिन कम से कम उस प्रश्न का उत्तर दें जब आप ऐसा करते हैं। – cHao

+0

हाँ, आप सही हैं ... –

2

पहला समाधान आलसी प्रतीत होता है, लेकिन वास्तव में नहीं।

एक कक्षा प्रारंभ की जाती है जब पहली बार एक स्थिर विधि/फ़ील्ड का उपयोग किया जाता है।

ऐसा नहीं है कि getInstance() केवल सार्वजनिक रूप से सुलभ स्थिर विधि/वर्ग के क्षेत्र है संभावना है। यह सिंगलटन का मुद्दा है।

फिर कक्षा प्रारंभ जब कोई 1 समय के लिए getInstance() कॉल कर रहा है। इसका मतलब है कि दो समाधान अनिवार्य रूप से आलस्य में समान हैं।

बेशक, दूसरा समाधान बेहतर दिखता है और बेहतर प्रदर्शन करता है।

+0

आलसी होना, सिंगलटन का कोई उदाहरण नहीं मिला जब तक इंस्टेंस() स्पष्ट रूप से लागू नहीं किया जाता है। वर्ग स्पष्ट रूप से दोनों बार लोड किया जाएगा। या क्या मैं कुछ न कुछ भूल रहा हूं? दूसरे समाधान में – Achow

+1

, उदाहरण केवल तब बनाया जाता है जब कक्षा प्रारंभ की जाती है; कक्षा केवल तब शुरू होती है जब एक स्थैतिक विधि/फ़ील्ड का उपयोग किया जाता है, यानी, जब getInstance() को आवंटित किया जाता है। – irreputable

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