定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
特点
A、 单例模式类只能有一个实例B、 单例模式类必须自己创建自己的唯一实例
C、 单例模式类必须给所有其他对象提供这一实例
参考:Android进阶之光
(1)饿汉模式
public class Singleton{
private static Singleton instance = new Singleton;
private Singleton(){}
public static Singleton getInstance(){ //获取实例对象
return instance;
}
}
1.构造函数为private 无法直接new创建实例。
保证了一个类只有一个实例。
饿汉方式 在类加载时就完成了初始化,所以类加载会比较慢,但获取对象的速度快。这种方式基于类的加载机制,避免了多线程同步的问题。在类加载的时候就完成实例化,没有达到懒加载的效果。如果从未使用过这个实例,则会造成内存的浪费。
字面理解懒加载:如果程序还没运行到这个地方就不进行相应的创建和初始化有利于节省资源提高性能。
(2)懒汉模式(线程不安全)
public class Singleton{
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉模式声明了一个静态对象,在用户第一次调用时初始化。
节约了资源,但第一次加载时需要实例化,反正稍慢,在多线程时不能正常工作。
(3)双重检查模式(DCL)
public class Singleton{
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
在getInstance方法中对Singleton进行了两次判空:第一次是为了不必要的同步,第二次是在Singleton等于null的情况下才创建实例。
缺点:第一次加载时反应稍慢一点,在高并发的环境下也有缺陷。(过段时间去研究 mark!)
(4)静态内部类单例模式(用这个吧,感觉这个最好了)
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法虚拟机加载SingletonHolder并初始化sInstance。
因为静态内部类要有引用以后才会加载到内存中。
为什么线程安全?因为类加载的过程是线程安全的(是不是才详查,暂时理解。)
(5)枚举单例(暂时不详学)