मेरे पास कई सिंगलटन कार्यान्वयन के लिए एक आम इंटरफ़ेस है। इंटरफेस प्रारंभिक विधि को परिभाषित करता है जो चेक अपवाद फेंक सकता है।सिंगलटन ऑब्जेक्ट्स की फैक्टरी: क्या यह कोड थ्रेड-सुरक्षित है?
मुझे एक कारखाने की आवश्यकता है जो मांग पर कैश किए गए सिंगलटन कार्यान्वयन को वापस कर देगा, और आश्चर्य होगा कि निम्नलिखित दृष्टिकोण थ्रेड-सुरक्षित है या नहीं?
Update1: करें, कोई भी 3 आंशिक रूप से पुस्तकालयों का सुझाव नहीं है के रूप में यह संभव लाइसेंस के मुद्दों की वजह से कानूनी मंजूरी प्राप्त करने के लिए :-)
UPDATE2 की आवश्यकता होगी: इस कोड को होने की संभावना में इस्तेमाल किया जाएगा होगा ईजेबी पर्यावरण, इसलिए यह अतिरिक्त धागे को बढ़ाने या उस तरह की सामग्री का उपयोग करने के लिए पसंद नहीं है।
interface Singleton
{
void init() throws SingletonException;
}
public class SingletonFactory
{
private static ConcurrentMap<String, AtomicReference<? extends Singleton>> CACHE =
new ConcurrentHashMap<String, AtomicReference<? extends Singleton>>();
public static <T extends Singleton> T getSingletonInstance(Class<T> clazz)
throws SingletonException
{
String key = clazz.getName();
if (CACHE.containsKey(key))
{
return readEventually(key);
}
AtomicReference<T> ref = new AtomicReference<T>(null);
if (CACHE.putIfAbsent(key, ref) == null)
{
try
{
T instance = clazz.newInstance();
instance.init();
ref.set(instance); // ----- (1) -----
return instance;
}
catch (Exception e)
{
throw new SingletonException(e);
}
}
return readEventually(key);
}
@SuppressWarnings("unchecked")
private static <T extends Singleton> T readEventually(String key)
{
T instance = null;
AtomicReference<T> ref = (AtomicReference<T>) CACHE.get(key);
do
{
instance = ref.get(); // ----- (2) -----
}
while (instance == null);
return instance;
}
}
मुझे लाइनों (1) और (2) के बारे में पूरी तरह से यकीन नहीं है। मुझे पता है कि संदर्भित ऑब्जेक्ट AtomicReference
में अस्थिर क्षेत्र के रूप में घोषित किया गया है, और इसलिए रेखा (1) में किए गए परिवर्तन तुरंत लाइन (2) पर दिखाई दे सकते हैं - लेकिन अभी भी कुछ संदेह हैं ...
इसके अलावा - मुझे लगता है ConcurrentHashMap
का उपयोग कैश में नई कुंजी डालने की परमाणुता को संबोधित करता है।
क्या आप इस दृष्टिकोण के साथ कोई चिंता देखते हैं? धन्यवाद!
पुनश्च: मैं स्थिर धारक वर्ग मुहावरा के बारे में पता है - और मैं इसे ExceptionInInitializerError
(जो किसी भी अपवाद सिंगलटन इन्स्टेन्शियशन दौरान फेंका में लपेटा जाता है) और बाद में NoClassDefFoundError
की वजह से उपयोग नहीं करते हैं जो कुछ मैं पकड़ने के लिए चाहते हैं नहीं कर रहे हैं । इसके बजाय, मैं इसे पकड़कर समर्पित चेक अपवाद का लाभ उठाना चाहता हूं और ईआईआईआर या एनसीडीएफई के स्टैक ट्रेस को पार्स करने के बजाए इसे शानदार तरीके से संभालना चाहता हूं।
धन्यवाद! तृतीय पक्ष lib मेरे मामले में एक विकल्प नहीं है ... – anenvyguest