zoukankan      html  css  js  c++  java
  • 设计模式之单例模式

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

    实现方式:

    1.最简单的方式

     public class Singleton
        {
            private static Singleton _instance;
            private Singleton()
            {
                Console.WriteLine("我被实例化了");
            }
            public static Singleton Instance
            {
                get
                {  
                    return _instance == null ? (new Singleton()) : _instance;
                }
            }       
        }

     上面代码保证3点:第一,类不能被实例化(私有构造函数);第二,类不能被继承(私有构造函数);第三,提供一个全局访问的静态属性。

    保证以上3点,单线程里我们就可以确保一个类只能提供一个实例,但是多线程下就不能确保了,我们看一下代码:

    View Code
     class Program
        {
            static void Main(string[] args)
            {
                MultWork multThread = new MultWork();
                multThread.StartMultThread();
                Console.ReadLine();
            }
        }
        public class Singleton
        {
            private static Singleton _instance;
            private static readonly Object padlock = new object();
            private Singleton()
            {
                Console.WriteLine("我被实例化了");
            }
            public static Singleton Instance
            {
                get
                {                
                    return _instance == null ? (new Singleton()) : _instance;
                }

            }

       }
        public class MultWork
        {
            private static readonly Object padlock = new object();
            /// <summary>
            
    /// 线程工作
            
    /// </summary>
            public static void DoSomeWork()
            {
                ///构造显示字符串
                string results = string.Empty;
                ///创建一个Sigleton实例
                Singleton MyCounter = Singleton.Instance;
                ///循环调用四次
                for (int i = 1; i < 5; i++)
                {               
                    results += "线程";
                    results += Thread.CurrentThread.Name.ToString();
                    results += "\n";
                }
            }
            public void StartMultThread()
            {
                Thread thred0 = Thread.CurrentThread;
                thred0.Name = "主线线程";
                Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
                thread1.Name = "thread1";
                thread1.Start();
                Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
                thread2.Name = "thread2";
                thread2.Start();
                Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
                thread3.Name = "thread3";
                thread3.Start();
                DoSomeWork();
            }

     我们新开了3个线程(包含主线程共4个线程),发现单例居然被实例化了4次,也就是说:每个线程独立实例化了Singleton,这可违背单例模式的初衷

     

    2.惰性实例化

     为了解决线程的安全问题,我们可以在单例中加一个锁,保证同一时刻只能有一个线程访问,一旦存在实例,将不再实例化单例类,重新设计单例类代码如下:

    View Code
    public class Singleton
        {
            private static Singleton _instance;
            private static readonly Object padlock = new object();
            private Singleton()
            {
                Console.WriteLine("我被实例化了");
            }
            public static Singleton Instance
            {
                get
                {
                    lock (padlock)
                        if (_instance == null)
                            _instance = new Singleton();
                    return _instance;

                }

            }
    }

     这样运行代码后发现无论启动多少个线程,都能保证类只有一个实例

     3.类型构造器方法(或者称为静态构造器法)

    这种做法的优点是:让线程的安全性交给CLR来负责,这也是.NET中推荐的一种单例设计方式,代码如下:

     

    View Code
     public  class Singleton
        {
            private static  Singleton _instance =null;        
            static Singleton()
            {
                Console.WriteLine("我被实例化了");
            }
            private Singleton()
            {
            }
            public static Singleton Instance
            {
                get
                {
                    if (_instance == null)
                        _instance = new Singleton();
                    return _instance;

                }
            }     
        }

    总之,以上就我在项目中经常使用的方式,当然还有其他更多的实现方式,你可以参看园子中其他大牛的文章,比如TerryLee的设计模式系列:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html


  • 相关阅读:
    合并两个排序的链表
    C#中调用C++的DLL文件
    C#获取进程的主窗口句柄
    在VS2008中编译纯c/c++程序并由c#调用过程 及 C++引用c#dll 模拟登陆实现
    C#多屏幕显示器编程
    Windows系统下的多显示器模式开发日记
    在 C# 中调用 C++
    C# 中调用C++ DLL (P/Invoke)
    C#多屏时控制窗体显示在哪个显示器上
    c# Winform 开发分屏显示应用程序
  • 原文地址:https://www.cnblogs.com/guanjie20/p/2344117.html
Copyright © 2011-2022 走看看