需求:某个类型的实例在程序的内存中只有1个,即类只实例化一次
实现 1 双层if 加锁 赖汉式单例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
/// <summary>
/// 单例模式
/// sealed 密封类不能被继承
/// </summary>
public sealed class Singleton
{
private Singleton()
{
Console.WriteLine("构造函数被调用一次1");
}
/// <summary>
/// 静态变量 在我们的程序中有 而且 仅有1个
/// </summary>
private static Singleton _Singleton = null;
/// <summary>
/// 保证线程安全
/// </summary>
private static object Singleton_Lock = new object();
/// <summary>
/// 通过静态方法,上端调用
/// </summary>
/// <returns></returns>
public static Singleton CreateInstance()
{
//判断对象是否为null
if (_Singleton == null)
{
//保证只有一个线程进入
lock (Singleton_Lock)
{
//除了第一个线程 后面进来的线程再在去判断一下对象是否为null
if (_Singleton == null)
{
_Singleton = new Singleton();
}
}
}
return _Singleton;
}
private int i = 0;
public void Show()
{
lock (Singleton_Lock)
{
int k = i + 1;
i = k;
}
Console.WriteLine("这里是Singleton.Show,{0}", i);
}
}
}
上端调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(() => {
Singleton.CreateInstance().Show();
});
}
Console.ReadKey();
}
}
}
实现2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
/// <summary>
/// 单例模式
/// sealed 密封类不能被继承
/// </summary>
public sealed class Singleton2
{
private Singleton2()
{
Console.WriteLine("构造函数被调用一次2");
}
/// <summary>
/// 静态变量 在我们的程序中有 而且 仅有1个
/// 静态对象会在第一次调用类的任何方式之前被初始化,而且静态对象只会初始化一次
/// </summary>
private static Singleton2 _Singleton = new Singleton2();
/// <summary>
/// 通过静态方法,上端调用
/// </summary>
/// <returns></returns>
public static Singleton2 CreateInstance()
{
return _Singleton;
}
private int i = 0;
public void Show()
{
lock (Singleton_Lock)
{
int k = i + 1;
i = k;
}
Console.WriteLine("这里是Singleton.Show,{0}", i);
}
}
}
上端调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(() => {
Singleton2.CreateInstance().Show();
});
}
Console.ReadKey();
}
}
}
实现3
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
/// <summary>
/// 单例模式
/// sealed 密封类不能被继承
/// </summary>
public sealed class Singleton3
{
private Singleton3()
{
Console.WriteLine("构造函数被调用一次3");
}
/// <summary>
/// 任何一个类,最多只能有一个无参数的静态构造函数
/// 该函数会在这个类第一次使用之前,被CLR调用,而且只调用一次,静态构造函数在程序中只执行一次
/// </summary>
static Singleton3()
{
_Singleton = new Singleton3();
}
private static Singleton3 _Singleton = null;
public static Singleton3 CreateInstance()
{
return _Singleton;
}
private int i = 0;
public void Show()
{
lock (Singleton_Lock)
{
int k = i + 1;
i = k;
}
Console.WriteLine("这里是Singleton.Show,{0}", i);
}
}
}
上端调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(() => {
Singleton3.CreateInstance().Show();
});
}
Console.ReadKey();
}
}
}
补充2句
普通对象 用完了 系统会释放 再new 又是一个新的
单例对象 用完了 系统永远也不会释放
单例模式 在多线程中 对竞争性资源的操作 该加锁还是要加 因为单例的线程并不是安全的