I have a common interface for a number of singleton implementations. The interface defines an initialization method that can throw a checked exception.
I need a factory that, on request, will return cached singleton implementations, and wonder if the following approach is thread safe?
UPDATE1: Please do not offer any third partly libraries, as this will require legal permission due to possible licensing problems :-)
UPDATE2: this code is likely to be used in an EJB environment, so it prefers not to create additional threads or use such things.
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);
I'm not quite sure about lines (1) and (2). I know that the reference object is declared as a mutable field in AtomicReference , and therefore the changes made in line (1) should immediately appear in line (2) - but still there are some doubts ...
Other than that - I think using ConcurrentHashMap addresses the atomicity of entering a new key into the cache.
Do you guys see any problems with this approach? Thanks!
PS: I know about a static class of classes and do not use it because of the ExceptionInInitializerError (which ends with any exception created when creating a single-line instance) and the subsequent NoClassDefFoundError , which is not what I want to catch. Instead, I would like to take advantage of the highlighted checked exception by catching it and processing it gracefully, rather than analyzing the EIIR or NCDFE stack trace.
source share