【设计模式】单例模式

2023 年 4 月 4 日 星期二(已编辑)
4

【设计模式】单例模式

单例模式是一种常用的设计模式,它确保在整个应用程序中只有一个实例被创建,并且提供了全局访问该实例的唯一途径。在多线程环境下使用单例模式时,需要考虑线程安全性,否则可能会出现多个实例被创建的问题。

本文将介绍如何使用 .NET 6 实现单例模式,并考虑到多线程的情况。使用双重检查锁定机制确保只有一个实例被创建,同时保证线程安全性。下面是示例代码: ```csharp public class Singleton { private static Singleton instance = null; private static readonly object objLock = new object();

// 私有构造函数,防止类被实例化
private Singleton() { }

// 获取 Singleton 实例的唯一途径
public static Singleton GetInstance()
{
    if (instance == null) // 第一次检查,减少锁的使用频率
    {
        lock (objLock) // 加锁
        {
            if (instance == null) // 第二次检查,确保只有一个实例被创建
            {
                instance = new Singleton();
            }
        }
    }
    return instance;
}

// 单例的某个公共方法
public void SomeMethod()
{
    Console.WriteLine("Call SomeMethod of Singleton.");
}

}


在上面的示例中,`Singleton`  类有一个私有构造函数,防止类被实例化。`GetInstance`  方法是获取  `Singleton`  实例的唯一途径。在方法中使用了双重检查锁定机制,确保只有一个实例被创建,并加锁以保证线程安全性。在  `SomeMethod`  方法中,可以编写单例的某个公共方法。

如果多个线程尝试同时访问  `GetInstance`  方法,`lock`  语句可以确保同时只有一个线程被允许进入临界区。第一次检查可以减少锁的使用频率,第二次检查可以确保只有一个实例被创建。这种方法既确保了线程安全性,又尽可能地减少了锁的使用频率,提高了性能。

下面是测试代码:
csharp

// 创建两个线程测试单例模式 Thread t1 = new Thread(() => { Singleton singleton = Singleton.GetInstance(); Console.WriteLine(singleton.GetHashCode()); }); Thread t2 = new Thread(() => { Singleton singleton = Singleton.GetInstance(); Console.WriteLine(singleton.GetHashCode()); });

// 启动线程并等待 t1.Start(); t2.Start(); t1.Join(); t2.Join();

在测试代码中,创建了两个线程分别获取 `Singleton` 实例,并输出其哈希码。如果单例模式实现正确,则两个线程输出的哈希码应该是相同的。运行测试代码,可以看到输出:

6417144 6417144 ``` 哈希码相同,单例模式实现正确。

总之,当需要在多个线程中使用单例模式时,应该考虑线程安全性。使用双重检查锁定机制可以确保只有一个实例被创建,并提高性能。通过 lock 语句确保同时只有一个线程被允许进入临界区,保证线程安全性。使用 .NET 6 实现单例模式可以方便地使用此设计模式。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...