Fork me on GitHub

设计模式系列一创建型之(单件模式)

1、意图

  •  保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2、适用性

  • 当类只有一个实例而且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

3、示意代码

  public class Singleton
    {
        private static Singleton instance;
        /// <summary>
        /// 程序运行时,创建一个静态只读的进程辅助对象
        /// </summary>
        private static readonly object _object = new object();
        /// <summary>
        /// 构造方法私有,外键不能通过New类实例化此类
        /// </summary>
        private Singleton()
        {
        }
        /// <summary>
        /// 此方法是本类实例的唯一全局访问点
        /// (双重加锁 Double-Check Locking)
        /// </summary>
        /// <returns></returns>
        public static Singleton GetInstance()
        {
            //先判断实例是否存在,不存在再加锁处理
            if (instance == null)
            {
                //在同一时刻加了锁的那部分程序只有一个线程可以进入,
                lock (_object)
                {
                    //如实例不存在,则New一个新实例,否则返回已有实例
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

 

 

4、实际应用

场景:要求对发送的消息做记录,同一时间内只允许一个进程对Txt文件的访问;

 

   /// <summary>
    /// MsgLog类
    /// </summary>
    public class MsgLog
    {
        private static object _helper = new object();
        private static MsgLog _instance;
        private static object _fileLock = new object();

        private MsgLog()
        {
        }

        public static MsgLog GetInstance()
        {
            lock (_helper)
            {
                if (_instance == null)
                {
                    _instance = new MsgLog();
                }
            }
            return _instance;
        }
        /// <summary>
        /// 消息记录
        /// </summary>
        public void SendMsgLog(string msg)
        {
            string filePath = System.AppDomain.CurrentDomain.BaseDirectory + "mail.txt";
            StreamWriter sw = null;
            FileStream fs = null;
            lock (_fileLock)
            {
                fs = !File.Exists(filePath) ? System.IO.File.Create(filePath) : new FileStream(filePath, FileMode.Append);
                sw = new StreamWriter(fs, Encoding.UTF8);
                sw.WriteLine("================================");
                sw.WriteLine(msg);
                sw.Flush();
                sw.Close();
            }
        }
    }

客户端调用:

     static void Main(string[] args)
        {
            MsgLog email1 = MsgLog.GetInstance();
            email1.SendMsgLog("发消息给迁梦余光......");

            MsgLog email2 = MsgLog.GetInstance();
            email2.SendMsgLog("再次发消息给迁梦余光......");

        }

  

执行结果:

 

posted @ 2014-09-17 15:51  迁梦余光  阅读(163)  评论(0编辑  收藏  举报