【问题标题】:Extend a class with double checked locking singleton in Java在Java中扩展一个具有双重检查锁定单例的类
【发布时间】:2015-08-02 07:27:09
【问题描述】:

我有这样的课:

public class Contact {

    private static volatile Contact instance;

    private List<Item> contacts = new ArrayList<>();
    private Context context;

    public static Contact getInstance(Context context) {
        Contact localInstance = instance;
        if (localInstance == null) {
            synchronized (Contact.class) {
                localInstance = instance;
                if (localInstance == null) {
                    instance = localInstance = new Contact(context);
                }
            }
        }
        return localInstance;
    }

    public Contact(BaseAuthActivity context) {
        this.context = context;
        update();
    }

在这里,我创建了一个类的实例,在 class 属性上进行同步。

我的项目中有很多这样的课程。有没有办法创建一个基类,它可以实现getInstance 方法,所以我不需要在我的所有类中保留这个代码?我尝试使用泛型,但没有运气。也许有一个我试图实现的例子?

【问题讨论】:

    标签: java singleton double-checked-locking


    【解决方案1】:

    这样做的一种方法是从您要实例化的Class 对象和您正在使用的单例实例中保存一个映射。假设你所有的类都有一个来自 Context 的公共构造函数,你可以使用反射来调用它:

    public class Contact {
    
        private static ConcurrentMap<Class<? extends Contact>, Contact> instances = 
            new ConcurrentHashMap<>();
    
        public static <T extends Contact> T getInstance
            (Context context, Class<T> clazz) {
    
            T instance = (T) instances.get(clazz);
            if (instance == null) {
                synchronized (clazz) {
                    instance = (T) instances.get(clazz);
                    if (instance == null) {
                        try {
                            Constructor<T> constructor = 
                                clazz.getConstructor(Context.class);
                            return constructor.newInstance(constructor);
                        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
                            // log
                            return null;
                        }
                    }
                }
            }
            return instance;
        }
    }
    

    【讨论】:

    • 谢谢你,穆雷尼克!我会试试看。
    猜你喜欢
    • 2016-04-03
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多