设计模式 | 单例模式 C#描述

	/*
	不安全的单例
	多线程访问时可能会创建多个对象
	*/
	public sealed class Singleton
	{
		private Singleton instance;

		//将构造函数变为私有,使得外部不可调用
		private Singleton() { }

		public static Singleton GetInstance()
		{
			if (instance == null)
			{
				instance = new Singleton();
			}
			return instance;
		}
	}

	/*
	多线程安全的单例
	通过锁定对象来阻止其他线程的访问
	*/
	public sealed class Singleton
	{
		private static Singleton instance;
		private static readonly object o = new object();

		private Singleton() { }

		public static Singleton GetInstance()
		{
			//全局判断
			if(instance == null)
			{
				//锁住一个对象,以保证在此域中,instance不被多个线程同时访问
				lock (o)
				{
					//局部判断,确保在加锁的过程中instance没有被创建
					if (instance == null)
					{
						instance = new Singleton();
					}
				}
			}

			return instance;
		}
	/*
	线程安全的只读单例
	缺点:会在需要使用之前创建
	*/
	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
		Lazy<Singleton> instance = new Lazy<Singleton>(()=> new Singleton());

		private Singleton() { }

		public static Singleton Instance => instance.Value;
	}
	/*
	线程安全的泛型只读单例
	惰性初始化
	*/
	public sealed class Singleton<T> where T : class, new()
	{
		//自引用
		//private static readonly
		//Lazy<Singleton<T>> instance = new Lazy<Singleton<T>>
		//	(
		//		() => new Singleton<T>()
		//		{
		//			person = new Person()
		//		}
		//	);

		//泛型引用
		private static readonly
		Lazy<T> instance = new Lazy<T>
			(
				() => new T()
			);

		private Singleton() { }

		//public static Singleton<T> Instance => instance.Value;
		public static T Instance => instance.Value;
	}
/* 测试类 */
namespace Singleton
{
	public class Person
	{
		public int ID { get; set; }
		public string Name { get; set; }

		public Person()
		{
			ID = 1;
			Name = "Abel";
		}
	}
}
/* 测试主程序 */
using System;

namespace Singleton
{
	class Program
	{
		static void Main()
		{
			SingletonTest();
		}

		private static void SingletonTest()
		{
			//Singleton instance = Singleton.Instance;

			Person p = Singleton<Person>.Instance;
		}
	}
}

调试时,可以在Lasy instance 处设置断点,第一次会进入执行创建instance对象,执行之后,移动黄色箭头到该条语句再次执行,发现没有调用创建语句,直接返回instance,查看变量字段值,和初始值一样。

注释为个人理解,如有错误,还望各位指正。

参考:https://www.cnblogs.com/mhg215/p/9795478.html

posted @ 2021-07-09 17:03  windin  阅读(43)  评论(0编辑  收藏  举报