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在使用之前調用,並且只調用了一次。所有也能夠保證唯一性;
結果如下:
註明:上面是參考其他文檔,如果設計到版權問題,麻煩聯繫。謝謝