安卓复习之旅—单例模式

单例模式是开发中最常用的一种模式,sharedPreference基本上是最常用的一种,下面就来看看单例模式的几种定义方式:

1、饿汉式单例类
饿汉式单例类是Java语言里最容易实现的单例类:

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {
    }

    public static EagerSingleton getInstance() {
        return instance;
    }
}

这个类被加载的时候,静态变量instance 就会被初始化,此时私有构造方法会被调用,单例类的唯一实例也就被创建出来了;
2、懒汉式单例类

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    synchronized public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

可以看到getInstance()方法加上了synchronized 关键字进行同步,这样的目的是处理多线程环境;http://blog.csdn.net/lin_t_s/article/details/53537430这篇文章介绍了使用多进程会产生的一些异常,其中就有单例模式失效。
饿汉式单例类一旦加载就会产生类实例,而懒汉式单例类被静态加载器加载的时候是不会将自己实例化的,从资源上来讲,比饿汉式单例类稍好,从速度和反应时间来讲,比饿汉式单例类稍慢一些;
getInstance 是一个被频繁调用的方法,如果使用 synchronized 修饰 getInstance 方法后必然会导致性能下降,使用双重校验锁提升性能。
双重校验锁

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {

            synchronized (LazySingleton.class) {
                if (null == instance) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

3、登记式单例类
不管是饿汉式还是懒汉式单例类,他们的构造方法都是私有的,也就不能够被继承,登记式单例类也就克服了这一缺点:

父类:

package singlemodle;

import java.util.HashMap;

public class RegSingleton {
    // 盛装类实例的容器
    private static HashMap registry = new HashMap();

    static {
        RegSingleton instance = new RegSingleton();
        //key未全类名
        registry.put(instance.getClass().getName(), instance);
    }

    protected RegSingleton() {
    };

    public static RegSingleton getInstance(String name) {
        if (name == null) {
            name = "singlemodle.RegSingleton";
        }
        if (registry.get(name) == null) {
            try {
                // 通过反射得到类实例
                registry.put(name, Class.forName(name).newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return (RegSingleton) registry.get(name);

    }

    // 测试用的方法
    public static void show() {
        System.out.println("我是登记单例类的父类");
    }
}

子类:

package singlemodle;

public class RegSingleton_Child extends RegSingleton {
    // 此处不能用private修饰,不然会报以下错误
    // Class singlemodle.RegSingleton can not access a member of class
    // singlemodle.RegSingleton_Child with modifiers "private"
    // Constructor<T>[] constructors = privateGetDeclaredConstructors((which ==
    // Member.PUBLIC));
    // 通过源码可以发现构造方法必须未public修饰的
    public RegSingleton_Child() {
    };

    public static RegSingleton_Child getInstance() {
        return (RegSingleton_Child) RegSingleton.getInstance("singlemodle.RegSingleton_Child");
    }

    // 测试用的方法
    public static void show() {
        System.out.println("我是登记单例类的子类");
    }
}

测试一下:

package singlemodle;

public class Test {
    public static void main(String[] args) {
        RegSingleton regSingleton = RegSingleton.getInstance(null);
        regSingleton.show();
        RegSingleton_Child regSingleton_Child = RegSingleton_Child.getInstance();
        regSingleton_Child.show();
    }
}

结果:

我是登记单例类的父类
我是登记单例类的子类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值