1.单线程单例:
/// <summary>
/// 单例模式
/// 1.单线程单例
/// 2.多线程单例--lock
/// 单例是在程序运行时,初始化对象内存,将会常驻内存,
/// 后期不会再实例化。保证内存唯一只初始化一次
/// </summary>
class Program
{
static void Main(string[] args)
{
///单线程单例模式
SingleInit1();
///多线程
TaskInit();
Console.ReadKey();
}
private static void TaskInit()
{
for (int i = 0; i < 10; i++)
{
Task task = new Task(() => {
SingleClass single = SingleClass.CreateSingleClass();
single.ShowText();
});
task.Start();
}
}
/// <summary>
/// 单线程单例
/// </summary>
private static void SingleInit1()
{
for (int i = 0; i < 10; i++)
{
SingleClass single = SingleClass.CreateSingleClass();
single.ShowText();
}
}
}
singleClass类
class SingleClass
{
private static SingleClass singleObject = null;
private SingleClass()
{
Thread.Sleep(5000);
Console.WriteLine("当前实例对象:{0},当前线程ID:{1}", this.GetType(), Thread.CurrentThread.ManagedThreadId);
}
public static SingleClass CreateSingleClass()
{
if (singleObject == null)
{
singleObject = new SingleClass();
}
return singleObject;
}
public void ShowText()
{
Console.WriteLine("调用显示方法");
}
}
演示结果:
singleInit()方法执行结果在单线程的情况下,内存中只会实例化一次SingleClass,显示结果如下:
TaskInit()方法执行,在多线程情况下,然而并不能保证实例化一次,显示结果如下:
由此,可见在多线程情况下,并没有保证SingleClass只实例化一次,如是改进如下:
static void Main(string[] args)
{
///单线程单例模式
//SingleInit1();
///多线程
//TaskInit();
///多线程-单例
TaskSingleInit();
Console.ReadKey();
}
private static void TaskSingleInit()
{
for (int i = 0; i < 10; i++)
{
Task task = new Task(() =>
{
TaskSingleClass taskSingle = TaskSingleClass.CreateTaskSingleClass();
taskSingle.ShowText();
});
task.Start();
}
}
TaskSingleClass对象
class TaskSingleClass
{
private static TaskSingleClass taskSingleClass = null;//实例化TaskSingleClass对象变量
private static Object lockObject = new Object(); //初始化Object,用于lock
private TaskSingleClass()
{
Thread.Sleep(1000);
Console.WriteLine("当前对象{0},线程Id{1}",this.GetType(),Thread.CurrentThread.ManagedThreadId);
}
public static TaskSingleClass CreateTaskSingleClass()
{
if (taskSingleClass == null)//在lock等待之前判断是否实例化,如果实例化直接返回。提升性能
{
lock (lockObject)
{
if (taskSingleClass == null)
{
taskSingleClass = new TaskSingleClass();
}
}
}
return taskSingleClass;
}
public void ShowText()
{
Console.WriteLine("方法调用");
}
}
TaskSingleClass类中对多线程进行了处理,在多个线程的情况下,保证了TaskSingleCalss只被实例化一次,运行结果如下:
静态构造函数初始化(简单)
public class StaticSingleClass
{
private static StaticSingleClass staticSingle = null;
private StaticSingleClass()
{
Console.WriteLine("构造函数");
Thread.Sleep(1000);
Console.WriteLine("当前对象{0},线程Id{1}", this.GetType(), Thread.CurrentThread.ManagedThreadId);
}
/// <summary>
/// 方式1 静态构造函数
/// </summary>
static StaticSingleClass()
{
Console.WriteLine("静态构造函数,在构造函数之前执行");//并且只执行一次,由CLR调用执行,并且只执行一次
staticSingle = new StaticSingleClass();
}
/// <summary>
/// 方式2 静态变量
/// </summary>
/// <returns></returns>
static StaticSingleClass singleStatic = new StaticSingleClass();
public static StaticSingleClass CreateSingleInit()
{
return staticSingle;
}
public void ShowText()
{
Console.WriteLine("调用方法");
}
}
StaticSingleClass对象中,并没有添加Lock,来处理多线程情况,而是使用static 构造函数和静态变量来处理多线程单例模式,是因为static代码块和static变量,是由CLR在使用之前调用,并且只调用了一次。所有也能够保证唯一性;
结果如下:
注明:上面是参考其他文档,如果设计到版权问题,麻烦联系。谢谢