单例模式的几种写法

时间:2021-05-08 05:34:49

单例模式的核心思想就是保证内存中存在一个实例

适用场景:多次及重复的调用类的实例,做重复的内容;全局管理及调用;提高效率的时候;


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
/// <summary>
/// 饿汉模式,类装载中完成实例化,
/// 1.避免出现多线程多次构造
/// 2.不调用会造成资源浪费
///
/// </summary>
class Singleton
{
public long Result { get; private set; }
public Singleton()
{
for(int i = 0; i < 10000000; i++)
{
Result += i;
}
Console.WriteLine("构造函数 执行");

}
~Singleton() {
Console.WriteLine("析构函数");
}

private static Singleton _Instance = new Singleton();

public static Singleton Instance
{
get
{
return _Instance;
}
}

public void Dispose()
{
if (_Instance != null)
{
_Instance = null;
Console.WriteLine("销毁");
}
}

}
/// <summary>
/// 饿汉模式,静态构造里完成实例化
/// 1.避免出现多线程多次构造
/// 2.不调用会造成资源浪费
///
/// </summary>
class Singleton2
{
public long Result { get; private set; }
public Singleton2()
{
for (int i = 0; i < 10000000; i++)
{
Result += i;
}
Console.WriteLine("构造函数 执行");

}
~Singleton2()
{
Console.WriteLine("析构函数");
}

private static Singleton2 _Instance = null;

static Singleton2()
{
_Instance = new Singleton2();
}

public static Singleton2 Instance
{
get
{
return _Instance;
}
}

public void Dispose()
{
if (_Instance != null)
{
_Instance = null;
Console.WriteLine("销毁");
}
}
}
/// <summary>
/// 懒汉模式,调用的时候实例化
/// 1.适用与单线程,不适合多线程,出现多次构造实力
/// 180,254
/// </summary>
class Singleton3
{
public long Result { get; private set; }
public Singleton3()
{
for (int i = 0; i < 10000000; i++)
{
Result += i;
}
Console.WriteLine("构造函数 执行");

}

~Singleton3()
{
Console.WriteLine("析构函数");
}

private static Singleton3 _Instance = null;

public static Singleton3 Instance
{
get
{
if(_Instance == null)
{
_Instance = new Singleton3();
}
return _Instance;
}
}

public void Dispose()
{
if(_Instance != null)
{
_Instance = null;
Console.WriteLine("销毁");
}
}
}

/// <summary>
/// 懒汉模式,双重检测,经典方法
/// </summary>
class Singleton4
{
public long Result { get; private set; }
public Singleton4()
{
for (int i = 0; i < 10000000; i++)
{
Result += i;
}
Console.WriteLine("构造函数 执行");

}

~Singleton4()
{
Console.WriteLine("析构函数");
}

private static Singleton4 _Instance = null;

private static object _testLock = new object();
public static Singleton4 Instance
{
get
{
if (_Instance == null)//所有的并发线程进入这里检测
{
lock (_testLock)//锁住一个线程,其他线程等待
{
if (_Instance == null)//第一个进入的线程开始创建实例,其他线程进入后需要检测是否已经创建过
{
_Instance = new Singleton4();
}
}
}
return _Instance;
}
}

public void Dispose()
{
if (_Instance != null)
{
_Instance = null;
Console.WriteLine("销毁");
}
}
}

}

客户端测试

  Console.WriteLine("-------------------------------------------------单线程分割线------------------------------------------------------");
Stopwatch watch = new Stopwatch();
watch.Start();

for (int i = 0; i < 100; i++)
{

Console.WriteLine("ID{0} Result {1},Thread {2}", i, Singleton4.Instance.Result, Thread.CurrentThread.ManagedThreadId);
}

watch.Stop();
Console.WriteLine("单线程中的单例耗时:{0}",watch.ElapsedMilliseconds);

Singleton3.Instance.Dispose();
GC.Collect();

Console.WriteLine("-------------------------------------------------多线程分割线------------------------------------------------------");
Stopwatch watch2 = new Stopwatch();
watch2.Start();

List<Task> taskList = new List<Task>();
TaskFactory taskFactory = new TaskFactory();

for (int i = 0; i < 100; i++)
{
taskList.Add(taskFactory.StartNew(() =>
{
Console.WriteLine("ID{0} Result {1},Thread {2}", i, Singleton4.Instance.Result, Thread.CurrentThread.ManagedThreadId);
}));



}
Task.WaitAll(taskList.ToArray());
watch2.Stop();
Console.WriteLine("多线程中的单例耗时:{0}", watch2.ElapsedMilliseconds);