C# 线程安全单例模式
一、单例模式核心概念单例模式作用保证整个项目运行期间有且仅有一个对象实例所有类、所有窗口、所有代码共享同一个对象数据。本案例核心场景全局唯一血量HP无论 new 多少个攻击者对象扣血全部作用在同一个HP上。二、单例模式三大固定特征必背私有构造函数禁止外部 new 对象私有静态全局对象存储唯一实例公共静态获取方法统一入口获取唯一对象加锁保证线程安全三、完整可运行代码去重、规整、修复1. 线程安全单例核心类Singletoninternal class Singleton { // 1. 静态全局唯一实例私有 public static Singleton instance null; // 线程锁对象保证多线程排队访问 static object locker new object(); // 2. 私有构造函数禁止外部 new private Singleton() { } // 3. 对外开放获取单例对象的入口方法线程安全 public static Singleton GetSingle() { // 互斥锁同一时间只允许一个线程进入代码块 lock (locker) { // 对象为空才创建保证只创建一次 if (instance null) { instance new Singleton(); } } return instance; } // 全局共享血量 public int HP 100; // 扣血方法每次扣除10点血量 public int SubHP() { return HP - 10; } }2. 攻击类 Class1、Class2复用单例// 第一个攻击类 public class Class1 { // 攻击方法调用全局单例扣血 public string Attack() { // 获取唯一单例对象调用扣血方法 return Singleton.GetSingle().SubHP().ToString(); } } // 第二个攻击类 public class Class2 { public string Attack() { return Singleton.GetSingle().SubHP().ToString(); } }3. WinForm 界面调用逻辑using System; using System.Windows.Forms; namespace _单例模式 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // 通过Class1对象调用攻击 private void button1_Click(object sender, EventArgs e) { Class1 c new Class1(); label1.Text c.Attack(); } // 通过Class2对象调用攻击 private void button2_Click(object sender, EventArgs e) { Class2 c new Class2(); label1.Text c.Attack(); } // 直接调用单例方法扣血 private void button3_Click(object sender, EventArgs e) { label1.Text Singleton.GetSingle().SubHP().ToString(); } // 直接访问静态实例扣血 private void button4_Click(object sender, EventArgs e) { label1.Text Singleton.instance.SubHP().ToString(); } } }四、代码运行逻辑核心精髓无论你执行以下哪种操作new Class1().Attack()new Class2().Attack()Singleton.GetSingle().SubHP()Singleton.instance.SubHP()全部操作的是同一个 Singleton 对象、同一个 HP 变量。初始 HP 100每点一次按钮 HP - 10数据全局共享、永久叠加生效。五、关键知识点解析1. 为什么构造函数私有防止外部随意new Singleton()一旦可以手动 new就会产生多个对象单例失效。2. lock 锁的作用多线程场景下多个线程同时判断 instancenull可能创建多个对象。lock 保证代码块排队执行同一时间仅一个线程创建对象实现线程安全。3. 两种获取单例方式区别Singleton.GetSingle()推荐经过判断锁安全规范Singleton.instance直接访问静态字段简单但不规范六、单例模式优缺点优点全局唯一对象节省内存资源全局数据共享所有模块操作同一数据线程锁保证多线程安全缺点职责过重代码耦合度高全局常驻内存程序运行期间不销毁七、面试必背口诀懒汉单例私有构造禁new造静态实例全局保lock上锁防多线程为空创建只一遭全局数据共享用单例唯一不乱跑。八、易错点总结单例对象全局唯一再多 new 业务类也不会新建单例不加 lock 的单例线程不安全构造函数必须 private否则单例模式失效单例内部字段是全局共享数据所有地方修改都会互相影响