Thread Safe Singleton Abstract class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
package com.damrakoc.java; import android.util.Log; import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.Map; /** * Created by damra on 08/08/2017. * USAGE: public class TestSingleton extends ThreadSafeSingleton<TestSingleton> { public static TestSingleton getInstance() { return ThreadSafeSingleton.getInstance(TestSingleton.class); } } */ @SuppressWarnings({"all"}) public abstract class ThreadSafeSingleton<T> { private static final Map<Class<? extends ThreadSafeSingleton>, ThreadSafeSingleton> INSTANCES = new HashMap<>(); private static final String TAG = ThreadSafeSingleton.class.getSimpleName(); private static class SingletonHolder<T> { private static <T> T getInstance(Class<T> clazz){ Constructor<T> constructor = (Constructor<T>) clazz.getDeclaredConstructors()[0]; constructor.setAccessible(true); try{ return constructor.newInstance(null); }catch (Exception e){ Log.d(TAG, "getInstance: "+e.getLocalizedMessage()); return null; } } } protected ThreadSafeSingleton() { Log.d(TAG, "Initializing ThreadSafeSingleton"); } protected static <T extends ThreadSafeSingleton<T>> T getInstance(Class<T> clazz) { if(INSTANCES.containsKey(clazz)) { return (T) INSTANCES.get(clazz); } else { try{ T instance = SingletonHolder.getInstance(clazz); INSTANCES.put(clazz, instance); return instance; }catch (Exception e ){ return null; } } } protected static <T extends ThreadSafeSingleton<T>> void putInstance(Class<T> clazz, T instance) { if(!INSTANCES.containsKey(clazz)) { INSTANCES.put(clazz, instance); } } } |