一.为什么要使用单例模式
在软件系统中,会有一些类,必须保证它们在系统中只存在一个实例,才能确保它们逻辑性正确、以及良好的效率,因为单例模式就应运而生了。
二.单例模式的代码实现
1.单线程单例模式的实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Singleton { public class SingleThread { private static SingleThread _instance = null; private static int _nCount = 0; private SingleThread() { } public static SingleThread GetInstance() { if(null == _instance) { _instance = new SingleThread(); _nCount++; } return _instance; } public void ShowSingleInfo() { Console.WriteLine("这是一个单线程单例模式:nCount值为{0}",_nCount); } } }
2.多线程单例模式
上述单线程模式在多线程下是不安全的,如果两个线程同时运行到if(null == _instance)判断是否被实例化,一个线程判断为True后,在进行创建_instance = new SingleThread();之前,另一个线程也判断(null == instance),结果也为True。这样创建的便不是一个类仅有一个实例了,违背了单例模式的原则。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Singleton { public class MultiThread { private static volatile MultiThread _instance = null; private static object lockHelper = new object(); private MultiThread() { } public static MultiThread GetInstance() { if(null == _instance) { lock(lockHelper) { if(null == _instance) { _instance = new MultiThread(); } } } return _instance; } public void ShowMultiThreadInfo() { Console.WriteLine("这是一个多线程单例模式"); } } }
3.静态单例模式的实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Singleton { public class StaticSingleton { public static readonly StaticSingleton _instance = new StaticSingleton(); private StaticSingleton(){} public void ShowStaticInfo() { Console.WriteLine("这是一个静态单例"); } } }
4.单例模式调用方法
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Singleton { class Program { static void Main(string[] args) { //单例模式调用 SingleThread.GetInstance().ShowSingleInfo(); MultiThread.GetInstance().ShowMultiThreadInfo(); StaticSingleton._instance.ShowStaticInfo(); Console.ReadKey(); } } }