团部培训笔记-设计模式-《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(s){
                   if(s==null){
                       s=new Single();
                   }
               }

          }
          return s;
      }
}

分析:

该实现为双重锁,即在方法中对class加锁。

注意,在锁内,实例可被重新初始化,所以对实例加锁无意义。

 

方式4:
public class Single{
     public static final Single s=new Single();

     private Single(){}
}

分析:

要保证两点:1、构造方法私有化――封装构造方法的可见性;2、实例是静态的: static (final);

 

方式5:
public Enum Single{
     S;
     private Single(){}
}

分析:

使用枚举来实现单例,避免多线程同步问题,以及绝对避免多次实例化问题;

 

四、注意点:

在多线程环境下,要注意考虑同步问题:1、如何实现 2、写单例

 

五、模式协作:

1、配合工厂模式:提供实例
2、配合亨元模式:copy机制,复用一个提供的实例

如:数据库连接池的应用,菜单树的应用
3、配合MVC模式:如servlet

 

六、项目应用:

public class PrecastMethodFactory {
 /**
  * 空白公式和公式法,这个公式可以用单例。
  * <p>
  * 2013年10月12日 团长 增加公式法的单例
  * 
  * @author �F�L
  * @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的);

 

七、单例模式总结:

1、保证上下文中只有一个单例
2、节约内存
3、实现方式要点:封装构造方法的可见性
4、注意事项:多线程操作
5、与其它模式协作:工厂模式,亨元模式,mvc模式等
6、项目应用:部分预测方法

你可能感兴趣的:(单例,设计模式)