设计模式- 单例模式
单例模式是一种创建型设计模式, 可以保证一个类型有且只有一个实例存在
单例模式的适用于什么场景
当一个类在程序运行期间只需要一个实例的时候, 就可以考虑将其做成单例模式
例如一些全局的配置, 用来储存程序运行期间全局的共享配置, 或者可以做一个简单的消息管道, 程序中所有地方只需要这一个消息管道来发送和接收消息
单例模式的实现
单例模式有多种实现方式, 但是都离不开非公有的构造函数和静态成员变量
下面根据我自己的经验, 介绍三种比较常见的实现
饿汉式
饿汉式在类型加载的时候就直接进行实例化
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton GetInstance() => instance;
}
饿汉式最简单方便, 总有人说饿汉式会浪费内存, 但是在大多数情况下这点内存浪费可以忽略不计, 相比起其他业务中的浪费, 九牛一毛都算不上
懒汉式
懒汉式在第一次调用GetInstance
的时候才进行实例化
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton GetInstance() => instance ??= new Singleton();
}
懒汉式这种在调用GetInstance
的时候才实例化的方式避免了大概率微不足道的内存浪费, 但又会出现线程安全问题
双重校验锁
双重校验锁通过加锁可以解决懒汉式多线程下的线程不安全问题
public class Singleton
{
private static volatile Singleton instance;
private static object lockobj = new Object();
private Singleton() { }
public static Singleton GetInstance()
{
if (instance == null)
{
lock (lockobj)
{
instance ??= new Singleton();
}
}
return instance;
}
}
但是用饿汉式就不需要这么麻烦
如何去使用
设计一个单例类用于记录服务器的在线人数
public sealed class LoginCounter
{
private static readonly LoginCounter instance = new LoginCounter();
private LoginCounter() { }
public static LoginCounter GetInstance() => instance;
private List<User> OnlineUsers = new List<User>();
public int LoginCount { get => OnlineUsers.Count; }
public void Login(User user)
{
if (OnlineUsers.Any(item => item.Name == user.Name))
return;
OnlineUsers.Add(user);
}
public void Logout(User user)
{
if (!OnlineUsers.Any(item => item.Name == user.Name))
return;
OnlineUsers.RemoveAll(item => item.Name == user.Name);
}
}
public class User
{
public string Name { get; set; }
}
有人登录进来就使用
LoginCounter.GetInstance().Login(user);
有人退出登录就使用
LoginCounter.GetInstance().Logout(user);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通