单例模式是一种常用的设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这在某些情况下很有用,特别是当系统中只应该存在一个实例时,如数据库连接、日志记录器、线程池等。
在C#中,实现单例模式有多种方式,下面介绍其中的两种常用方式:
饿汉式单例模式:
这种方式在类加载时就创建了实例,因此称为“饿汉式”。它的优点是实现简单,线程安全,但缺点是可能造成资源浪费,因为不管是否使用都会创建实例。
public sealed class Singleton
{private static readonly Singleton instance = new Singleton();private Singleton() { }public static Singleton Instance{get { return instance; }}
}
懒汉式单例模式:
这种方式在需要时才创建实例,称为“懒汉式”。它的优点是节省资源,但需要考虑线程安全性,可以使用锁或者双重检查锁定等方式来保证线程安全。
public sealed class Singleton
{private static readonly object padlock = new object();private static Singleton instance = null;private Singleton() { }public static Singleton Instance{get{lock (padlock){if (instance == null){instance = new Singleton();}return instance;}}}
}
常见的场景下使用单例模式包括:
- 数据库连接:确保在整个应用程序中只有一个数据库连接实例。
- 日志记录器:确保在整个应用程序中只有一个日志记录器实例。
- 配置管理器:确保在整个应用程序中只有一个配置管理器实例。
- 缓存:确保在整个应用程序中只有一个缓存实例。
单例模式在需要确保只有一个实例存在并且提供全局访问点的情况下是非常有用的。
下面写一个一个基于懒汉式单例模式的缓存管理器示例:
using System;
using System.Collections.Generic;public sealed class CacheManager
{// 使用静态变量存储唯一实例private static volatile CacheManager instance;// 使用双重锁定确保线程安全private static readonly object syncRoot = new object();// 使用字典存储缓存数据private Dictionary<string, object> cacheData;// 私有构造函数,防止外部实例化private CacheManager(){cacheData = new Dictionary<string, object>();}// 全局访问点public static CacheManager Instance{get{if (instance == null){lock (syncRoot){if (instance == null){instance = new CacheManager();}}}return instance;}}// 添加数据到缓存public void Add(string key, object value){cacheData[key] = value;}// 从缓存中获取数据public object Get(string key){if (cacheData.ContainsKey(key)){return cacheData[key];}else{Console.WriteLine($"Key '{key}' not found in cache.");return null;}}
}class Program
{static void Main(string[] args){// 使用单例模式获取缓存管理器实例CacheManager cacheManager = CacheManager.Instance;// 向缓存中添加数据cacheManager.Add("key1", "value1");cacheManager.Add("key2", "value2");// 从缓存中获取数据Console.WriteLine(cacheManager.Get("key1")); // 输出:value1Console.WriteLine(cacheManager.Get("key2")); // 输出:value2Console.WriteLine(cacheManager.Get("key3")); // 输出:Key 'key3' not found in cache.// 尝试通过构造函数实例化新的对象,将无法实现// CacheManager anotherInstance = new CacheManager(); // 报错:CacheManager.CacheManager() is inaccessible due to its protection level}
}