《单例模式》你需要注意的问题

 

单例模式大家都很熟悉,但是使用过程中,稍微不注意就会出现大问题。

 

单例模式:该类在整个系统生命周期中 有且只有一个 实例。

 

 

 

单例的创建:

注意问题:

  1. 构造函数 私有化 :保证 实例化该类通过统一的接口
  2. 提供一个统一的接口获取类的实例
  3. 保证线程同步

 例如:

public   class  CommonQuery
{

        
private  CommonQuery() { }

        
object  aLocker  =   new   object ();
        
static   readonly  CommonQuery _cmQuery  =   null ;

        
public   static  CommonQuery GetCommonQuery()
        {
          if (_cmQuery != null )
           {return _cmQuery;}
       lock (aLocker)
       {
         if (_cmQuery == null )
         {
           _cmQuery  =   new  CommonQuery();
         }
      
       }
       return  _cmQuery;
        }
}

 

 

单例中应该避免的问题:

  1. 避免无限递归调用
  2. 尽量少将数据或其他类的实例保存到该单例类中的全局变量中(如果有必要除外)

 

以上2点问题主要针对内存的问题,因为单例是在整个系统生命周期中都一直存在,如果有大量信息被单例保存,可想而知,我们的内存伤不起啊,

导致的结果就是 内存溢出!

 

场景:

多任务定时采集某网站数据

该需求 核心我一般这么设计:至少2个类

  1. CommonQuery:单例,负责 采集任务初始化、线程控制、具体采集任务调度、采集结果/错误等后续处理、通知前端UI
  2. WebWorker:非单例,负责具体采集任务,执行结果将反馈给CommonQuery


 核心序列图:

 

 

核心类图:

 

 

基本上核心 就是上面2个类,

执行流程是:在CommonQuery中的 Start()方法中,生成N个(根据多线程需要)webWorker对象,执行具体任务,当该任务执行完成或者出错以后,便通过事件EFinished或者EError来

通知CommonQuery,此时CommonQuery 根据实际情况来处理是继续新建任务来执行,还是判断整个任务结束,通知前台UI。(整个过程采用多线程异步)

 

 注意点:

  1. 在CommonQuery中 不需要保存任何webworker实例!应该在Start()方法里面去new WebWorker对象
  2. 在WebWorker的EFinished/EError事件处理中(在CommonQuery中处理),千万别调用新的一轮采集任务的开始!(此时造成无限递归!灰常危险!!)
  3. 检查CommonQuery,尽量减少将变量保存下来

这几点主要针对内存的建议,一般这种采集任务执行时间都较长,有时候需要连续几天不停的采集,此时如果设计的有问题,出现以上3中情况,呵呵,您的内存伤不起啊。。。

 

 

 

 

 

 C#技术交流: 64913828

 

 

 

 

 

转载于:https://www.cnblogs.com/bboy/archive/2011/08/26/2154112.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值