团部培训笔记-设计模式-《2013-11-19 单例模式》
按:本文为ATIP团内部培训笔记,主讲人: winters1224,记录人: hunterkathy,转载请注明出处;
一、单例模式的概念
单例,即单一实例;
单例模式,保证整个系统的上下文中只有一个类的实例;
系统上下文:即ClassLoader;
第三方定义上下文:SpringIOC
二、单例模式的作用
1、节约内存:内存中只保留一份和实例相关的资源
应用:如配置文件和缓存
2、控制多线程同步
任意多个线程,都只访问一个实例,天然的实现“写同步”
三、单例模式的实现
方式1
public class Single{
public static Single s;
private Single(){}
public static Single getInstance(){
if(s==null){
s=new Single();
}
return s;
}
}
分析
方式1只适合单线程,当多个线程读进来,同时判断s==null时,将导致创建多个实例。
方式2
public class Single{
public static Single s;
private Single(){}
public static synchronized Single getInstance(){
if(s==null){
s=new Single();
}
return s;
}
}
分析
方式2的方法中增加了同步管理,多个线程之间,实现后进入者等待机制,满足了同步需求;
但是该实现中对整个方法加了同步锁,无需同步实现的操作也被加锁,存在性能问题;
另外,synchronized对环境要求苛刻,在特殊情况下将失效,如多cpu的情况。
方式3
public class Single{
public static Single s;
private Single(){}
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if(s==null){
s=new Single();
}
}
}
return s;
}
}
分析
该实现为双重锁,即在方法中对class加锁。
注意,在锁内,实例可被重新初始化,所以对实例s加锁无意义。必须对所在类或其它实例加锁
方式4
public class Single{
public static final Single s=new Single();
private Single(){}
}
分析
要保证两点:
- 构造方法私有化——封装构造方法的可见性;
- 实例是静态的: static (final);
方式5
public Enum Single{
S;
private Single(){}
}
分析
使用枚举来实现单例,避免多线程同步问题,以及绝对避免多次实例化问题;
四、注意点
在多线程环境下,要注意考虑同步问题:
- 如何实现
- 写单例
五、模式协作
- 配合工厂模式:提供实例
- 配合亨元模式:copy机制,复用一个提供的实例 如:数据库连接池的应用,菜单树的应用
- 配合MVC模式:如servlet
六、项目应用
public class PrecastMethodFactory {
/**
* 空白公式和公式法,这个公式可以用单例。
* <p>
* 2013年10月12日 团长 增加公式法的单例
*
* @author 團長
* @since 2013-9-9
*/
private static final PremethodModel METHOD_BLANK = new BlankFormulaMethodModel(),
METHOD_FMLA = new FormulaMethodModle();
……
}
Spring IOC配置:
<bean id="BaseDBService"
class="com.sinosig.evaluation.base.service.impl.DefaultBaseDBServiceImpl">
<property name="dao" ref="BaseMybatisDao" />
<property name="batchDao" ref="BaseMybatisDao" />
</bean>
注:未定义scope的,默认都是SpringIOC的单例(不是指ClassLoader的);
七、单例模式总结
- 保证上下文中只有一个单例
- 节约内存
- 实现方式要点:封装构造方法的可见性
- 注意事项:多线程操作
- 与其它模式协作:工厂模式,亨元模式,mvc模式等
- 项目应用:部分预测方法
本文出自 “ ATIP團戰術策劃部” 博客,请务必保留此出处 http://atip3.blog.51cto.com/6312771/1331073