Singleton单件模式C#版

目录

单线程

静态属性

静态构造器

多线程  

测试


有时候需要在程序中保证一个类只能有一个实例,并且提供一个该实例的全局访问点,这时候就需要利用单件模式。所有的代码是在控制台应用中可以运行的。

单线程

静态属性

用静态属性和私有构造器来实现单例模式,静态属性确保全局只有一个实例,私有构造器确保外部无法构造该类实例,通过对静态属性的第一次访问,创建该类的一个实例,以后所有的对属性的访问都是对该实例的访问。

静态构造器

class Singleton
{
    public static readonly Singleton Instance = new Singleton();

    private Singleton()
    {
    }
}

静态构造器不仅支持单线程,也支持多线程。上述字段初始化方式称为内联初始化,等效于下述代码。

class Singleton
{
    public static readonly Singleton Instance;

    static Singleton()
    {
        Instance = new Singleton();
    }

    private Singleton()
    {

    }
}

多线程  

多线程情况下,假设线程1和2同时第一次访问Singleton.Instance,那么线程1就会新建一个实例,与此同时,线程2也会新建一个实例,因此,为了确保线程安全,我们需要设置线程同步锁。这里,设置双重保障,用volatile关键字保证编译器在编译过程中不会对代码进行调整,同步锁lockHelper保证不会有两个线程同时访问instance字段。

class Singleton
{
    private static volatile Singleton instance;
    private static object lockHelper = new object();

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (lockHelper)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

    private Singleton()
    {
    }
}

测试

这里测试一下是否实现我们的单例模式,Object.GetType()函数返回的是类名称,为了比较两个实例是否相同,需要用到反射,具体来说使用System.Object.ReferenceEquals函数,具体代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingletonMode
{
    class Program
    {
        static void Main(string[] args)
        {
            Singleton t1 = Singleton.Instance;
            Singleton t2 = Singleton.Instance;
            Console.WriteLine("t1和t2类型" + t1.GetType().ToString());
            Console.Write("t1和t2类型是否相等:");
            Console.WriteLine(t1.GetType() == t2.GetType());
            Console.Write("t1和t2实例是否相等:");
            Console.WriteLine(System.Object.ReferenceEquals(t1, t2));
            Console.WriteLine("\n");

            Student s1 = new Student();
            Student s2 = new Student();
            Console.WriteLine("s1和s2类型" + s1.GetType().ToString());
            Console.Write("s1和s2类型是否相等:");
            Console.WriteLine(s1.GetType() == s2.GetType());
            Console.Write("s1和s2实例是否相等:");
            Console.WriteLine(System.Object.ReferenceEquals(s1, s2));

            Console.ReadKey();
        }
    }

    
}
class Singleton
{
    public static readonly Singleton Instance;

    static Singleton()
    {
        Instance = new Singleton();
    }

    private Singleton()
    {

    }
}

class Student
{

}


代码输出结果

t1和t2类型Singleton
t1和t2类型是否相等:True
t1和t2实例是否相等:True


s1和s2类型Student
s1和s2类型是否相等:True
s1和s2实例是否相等:False

猜你喜欢

转载自blog.csdn.net/Abecedarian_CLF/article/details/81902222
今日推荐