单例模式是一种应用非常广泛的设计模式,用于保证一个类在程序生命周期内只能创建一次,并提供全局唯一的访问这个类的方法,也就是getInstance方法。单例有两种常用的写法:懒汉式和饿汉式。
懒汉式举例:
public class SingletonLan {
// 3 定义静态变量来存储创建好的类实例
private static SingletonLan instance = null;
// 1 私有化构造函数
private SingletonLan(){
}
// 2 定义静态方法提供类的实例
public static SingletonLan getInstance(){
// 4 判断存储类实例的变量是否存在
if(instance == null){
// 4.1 不存在就创建
instance = new SingletonLan();
}
// 4.2 存在的话就直接返回
return instance;
}
}
饿汉式举例:
public class SingletonE {
// 1 私有化构造函数
private SingletonE(){
}
// 3 定义一个静态变量保存类的实例
private static SingletonE instance = new SingletonE();
// 2 定义一个静态类来提供类实例
public static SingletonE getInstance(){
// 4 返回创建好的实例
return instance;
}
}
懒汉式与饿汉式的区别:
- 懒汉式是延迟加载的,当使用到单例时才开始实例化,而饿汉式是程序开启就实例化完成了。
- 懒汉式不是线程安全的,而饿汉式线程安全。
单例模式一般在缓存的时候使用,当某些外部资源频繁的被使用时,可以先将这些资源读到内存中,下次访问的时候就可以直接从内存中读取了,这样就可以节省大量的时间。在Android开发中解析配置文件的Manager、Sharepreference的管理器一般都是使用单例。缓存是一种典型的空间换时间的方案。
实际项目应用:TreeAccessoryStateManager
public class TreeAccessoryStateManager {
public static final int ACCE_STATUS_NOT_BUY = 0;
public static final int ACCE_STATUS_BOUGHT_NOT_USE = 1;
public static final int ACCE_STATUS_BOUGHT_USE = 2;
// 此处使用饿汉式单例,主要是为了确保线程安全
private static final TreeAccessoryStateManager instance = new TreeAccessoryStateManager();
public static TreeAccessoryStateManager getInstance() {
return instance;
}
private Map<Integer, GoodsItem> accessoryMap;
private TreeAccessoryStateManager() {
//由于这个map在主线程和render thread都有频繁改动,改成ConcurrentHashMap,暂时避免大部分问题。
accessoryMap = new ConcurrentHashMap<Integer, GoodsItem>();
}
public int getAcceStatus(int acceId) {
GoodsItem goodsItem = accessoryMap.get(acceId);
if (goodsItem != null) {
return goodsItem.getStatus();
}
return ACCE_STATUS_NOT_BUY;
}
}