做Android开发的程序猿,应该大多数第一个比较熟悉的设计模式都是单例模式吧。今天我们就来一起再学习一下单例模式的各种实现。
单例模式的特点:对外只提供唯一的一个实例对象
单例模式的实现思路如下:
1.私有化构造方法(不对外开放)
2.对外提供一个获取本类实例的静态方法
3.确保一个类只有一个实例对象
单例模式的常见实现方式有如下几种:
1.饿汉模式,(不管吃不吃得下,先把碗装满)
public class Singleton {
private static final Singleton instance=new Singleton();//恶汉模式,直接先实例化
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
2.懒汉模式,(需要的时候再去获取)
//懒汉模式
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
public static synchronized Singleton getInstance(){//同步控制,避免多线程的状况多创建了实例对象
if (singleton==null){
singleton=new Singleton();//在需要的时候在创建
}
return singleton;
}
}
3.双重检查锁模式,(在需要创建对象的时候再进行同步锁操作,即如果实例对象已经创建,那么多线程的状态下可以同时获取到实例对象)
//双重检查锁模式
public class Singleton_doubleCheck {
private static Singleton_doubleCheck instance;
private Singleton_doubleCheck(){
}
public static Singleton_doubleCheck getInstance(){//方法无需同步,各线程同时访问
if (instance==null){
synchronized (Singleton_doubleCheck.class){//在创建对象时再进行同步锁定
if (instance==null){
instance=new Singleton_doubleCheck();
}
}
}
return instance;
}
private Object readResolve() throws ObjectStreamException{
return instance;
}
}
单例模式的其他实现方式:
5.枚举模式,先看一下枚举的几个主要特征:
a.枚举和一般类一样有自己的构造方法,方法,成员变量;
b.枚举有默认私有构造方法;
c.枚举实例在任何情况都是一个单例,并且默认枚举的实例创建是线程安全的。。。
是不是完成符合单例模式的特征,来看一下实现
//枚举模式
public enum SingletonEnum {
INSTANCE;//不能用new关键字,枚举实例用一个全局变量表示,而且必须放到类的最开始
/**
* 在其他地方可以用如下方法调用
* SingletonEnum.INSTANCE.sayHello();
*/
public void sayHello(){
Log.i("SingletonEnum","hello");
}
}
6.静态内部类实现的单例,(摘自《Android源码设计模式解析与实战》。当第一次加载Singleton类时不会初始化instance,只有在调用了getSingleton方法的时候才会触发instance被初始化。因此,第一次调用get'Singleton方法会导致虚拟机加载SingletonManager类,这种方式不仅能确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化。所以单例模式推荐使用这种方式实现)。关于类加载机制请看:深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)
//静态内部类模式
public class Singleton {
private Singleton() {
}
public static Singleton getSingleton(){
return SingletonManager.instance;
}
public static class SingletonManager {
private static final Singleton instance = new Singleton();
}
}
以上为本次单例模式的个人观点,欢迎大家指正!