设计模式:单例模式
1. 单例模式的应用
多用于程序只需要一个实例,通常是很消耗资源的类,例如:线程池,数据库,i/o,缓存,网络请求等,由于比较消耗资源,所以没必要创建多个实例。
2.单例模式举例
- 饿汉式
public class SingletionStarving {
private static final SingletionStarving mInstance = new SingletionStarving();
private SingletionStarving() {
}
public static SingletionStarving getInstance() {
return mInstance;
}
}
1、构造函数用private修饰,外部无法访问
2、声明静态对象时就初始化
3、static关键字修饰,静态变量,存储在内存中,只有一份数据。
4、final关键字,只初始化一次,所以mInstance实例只有一个。
- 懒汉式
public class SingletionSlacker {
private static SingletionSlacker mInstance;
private SingletionSlacker() {}
public static synchronized SingletionSlacker getInstance() {
if (mInstance == null) {
mInstance = new SingletionSlacker();
}
return mInstance;
}
}
1、构造函数用private修饰,外部无法访问
2、使用的时候即调用getInstance的时候才初始化
3、static关键字修饰,静态变量,存储在内存中,只有一份数据。
4、synchronized线程安全,多线程情况下单例的唯一性
5、缺点:没次调用getInstance都会同步一次,浪费资源
- DCL式(Double Check Lock)
public class SingletionDLC {
private static SingletionDLC mInstance;
private SingletionDLC() {}
public static SingletionDLC getmInstance() {
if (mInstance == null) {
synchronized (SingletionDLC.class) {
if (mInstance == null) {
mInstance = new SingletionDLC();
}
}
}
return mInstance;
}
}
//在饿汉式2层判空
1、构造函数用private修饰,外部无法访问
2、使用的时候即调用getInstance的时候才初始化
3、static关键字修饰,静态变量,存储在内存中,只有一份数据
4、synchronized线程安全,多线程情况下单例的唯一性
5、两次判断空,避免多次同步(synchronized)
缺点
private static SingletionDLC mInstance;
private SingletionDLC() {}
public static SingletionDLC getmInstance() {}
由于jvm特性,允许乱序执行,上面三句代码顺序不定,那么就可能出现DCL失效的问题。
步骤一、倘若A线程执行getmInstance(),还没执行构造方法SingletionDLC()
步骤二、此时B线程调用getmInstance()。因为A已经执行getmInstance(),所以mInstance不为空就直接获取。
步骤三、由于B直接获取,而真实情况是A线程构造方法还未执行,所以mInstance就为空了。
虽然此情况发生概率较小,但也是一种情况。为了解决这种情况,java1.6开始加入volatile关键字
private volatile static SingletionDLC mInstance;
public class SingletionDLC {
private volatile static SingletionDLC mInstance;
private SingletionDLC() {}
public static SingletionDLC getmInstance() {
if (mInstance == null) {
synchronized (SingletionDLC.class) {
if (mInstance == null) {
mInstance = new SingletionDLC();
}
}
}
return mInstance;
}
}
- 静态内部类方式
public class SingletionInternalClass {
private SingletionInternalClass() {}
public static SingletionInternalClass getInstance() {
return SingletionInternalClassHolder.instance;
}
private static class SingletionInternalClassHolder {
private static final SingletionInternalClass instance = new SingletionInternalClass();
}
}
//推荐用这种模式,同时也能保证线程的安全,利用率也很高,缺点是第一次比较慢
- 枚举类型
public enum SingletionEmum {
INSTANCE;
}
//这种模式简单,代码少,同时也达到线程安全,但是在内存中会有2份内存的开销
单例模式详解
1205

被折叠的 条评论
为什么被折叠?



