设计模式-Singleton

[b]单例模式:[/b]
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。


[b]单例模式的特点:[/b]
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。


单例模式是最简单的设计模式,但是完全使用java构造一个线程安全的高效的单例,是需要有一定线程安全理论基础的,甚至需要理解java的内存模型!

JDK中的使用案例:
java.lang.Runtime
java.lang.NumberFormat

下面是三种最常用的构造单例的形式,并一一分析使用场景!

[b]1、非延迟加载的单例类(饿汉式单例类)。[/b]

/**
* 非延迟加载(这种是比较建议的,但是会造成启动较慢,不过线程安全,思路也简单)
* @author xinchun.wang
*
*/
public class SingletonDesign {
private static SingletonDesign instance = new SingletonDesign();

/**
* 必须为私有
*/
private SingletonDesign(){

}

/**
* 必须为静态
* @return
*/
public static SingletonDesign getInstance() {
return instance;
}
}


[b]2、二次检查的方式(DCL)。[/b]


/**
* 延迟加载(二次检查的方式)
* @author xinchun.wang
*
*/
public class SingletonDesignDoubleCheck {
/**
* 此处必须由volatile 修饰
*/
private volatile static SingletonDesignDoubleCheck instance = null;

/**
* 必须为私有
*/
private SingletonDesignDoubleCheck() {

}

/**
* 必须为静态
*
* @return
*/
public static SingletonDesignDoubleCheck getInstance() {
if (instance == null) {
synchronized (SingletonDesignDoubleCheck.class) {
//必须再次判断,已防止多次实例化
if(instance == null){
instance = new SingletonDesignDoubleCheck();
}
}
}
return instance;
}
}

此处重点要理解 为什么instance 要用volitile修饰,大家都知道volitile 实现的效果有:内存可见性,代码重排序。那么此处是用到那个效果呢?

其实此处最重要的是重排序,而非内存可见性:即使没有保证内存可见性的效果,最多也就是再次进入synchronized 块,内部仍然是可以确保逻辑的正确性的。当然内存可见性可以确保写线程写入后,读线程立即可以看到而不用再次获取SingletonDesignDoubleCheck.class锁 ,效率更高。

此处的重排序关键是搞清楚到底是那段代码的重排序,以及导致什么样的一个效果?
答案是:[b]instance 赋值指令 和 SingletonDesignDoubleCheck 构造函数里成员常量的重排序,非法的效果是:赋值在前,初始化在后,这样赋值的instance是没有完全初始化的,其他线程就会看到不完整的instance实例!!![/b]
这样的分析,不知道您是否理解~

[b]3、利用了java的类加载机制的一个实现(这个是实际应用中最推荐的方式,但是这种方式在某些需要定期更新的需求,是做不到的,必须求救于DCL的方式)[/b]

/**
* holder方式(这种方式主要是利用了java的类加载机制)
* @author xinchun.wang
*
*/
public class SingletonDesignByHolder {
private static class SingletonDesignHolder{
private static final SingletonDesignByHolder instance = new SingletonDesignByHolder();
}

/**
* 必须为私有
*/
private SingletonDesignByHolder(){

}

/**
* 必须为静态
* @return
*/
public static SingletonDesignByHolder getInstance() {
return SingletonDesignHolder.instance;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值