程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Singleton設計模式的C#實現(下)

Singleton設計模式的C#實現(下)

編輯:關於C語言
(接上部分)

以下為Main函數,本程序的測試入口:

using System;

namespace csPattern.Singleton

{

public class RunMain

{

public RunMain() {}

static public void Main(string[] args)

{

MutileThread.MutileClient myClient = new MutileThread.MutileClIEnt();

myClient.ClIEntMain();

System.Console.ReadLine();

}

}

}



執行結果如下:

線程Thread 1報告: 當前counter為: 2

線程Thread 1報告: 當前counter為: 4

線程Thread 1報告: 當前counter為: 5

線程Thread 1報告: 當前counter為: 6

線程Thread 3報告: 當前counter為: 7

線程Thread 3報告: 當前counter為: 8

線程Thread 3報告: 當前counter為: 9

線程Thread 3報告: 當前counter為: 10

線程Thread 0報告: 當前counter為: 1

線程Thread 0報告: 當前counter為: 11

線程Thread 0報告: 當前counter為: 12

線程Thread 0報告: 當前counter為: 13

線程Thread 2報告: 當前counter為: 3

線程Thread 2報告: 當前counter為: 14

線程Thread 2報告: 當前counter為: 15

線程Thread 2報告: 當前counter為: 16



由於系統線程調度的不同,每次的執行結果也不同,但是最終結果一定是16。

方法一中由於實例一開始就被創建,所以instance()方法無需再去判斷是否已經存在唯一的實例,而返回該實例,所以不會出現計數器類多次實例化的問題。



使用方法二:

using System;

using System.Threading;

using System.Runtime.CompilerServices;

namespace csPattern.Singleton

{

public class Counter_lazy

{

static Counter_lazy uniCounter;

private int totNum = 0;

private Counter_lazy()

{

Thread.Sleep(100); //假設多線程的時候因某種原因阻塞100毫秒

}

[MethodImpl(MethodImplOptions.Synchronized)] //方法的同步屬性

static public Counter_lazy instance()

{

if (null == uniCounter)

{

uniCounter = new Counter_lazy();

}

return uniCounter;

}

public void Inc() { totNum ++;}

public int GetCounter() { return totNum;}

}

}

不知道大家有沒有注意到instance()方法上方的[MethodImpl(MethodImplOptions.Synchronized)] 語句,他就是同步的要點,他指定了instance()方法同時只能被一個線程使用,這樣就避免了線程0調用instance()創建完成實例前線程1就來調用instance()試圖獲得該實例。

根據MSDN的提示,也可以使用lock關鍵字進行線程的加鎖,代碼如下:

using System;

using System.Threading;

namespace csPattern.Singleton

{

public class Counter_lazy

{

static Counter_lazy uniCounter;

static object myObject = new object();

private int totNum = 0;

private Counter_lazy()

{

Thread.Sleep(100); //假設多線程的時候因某種原因阻塞100毫秒

}

static public Counter_lazy instance()

{

lock(myObject)

{

if (null == uniCounter)

{

uniCounter = new Counter_lazy();

}

return uniCounter;

}

}

public void Inc() { totNum ++;}

public int GetCounter() { return totNum;}

}

}



lock()是對一個對象加互斥鎖,只允許一個線程訪問其後大括號中語句塊,直到該語句塊的代碼執行完才解鎖,解鎖後才允許其他的線程執行其語句塊。

還可以使用Mutex類進行同步,定義private static Mutex mut = new Mutex();後,修改instance()如下,同樣可以得到正確的結果:

static public Counter_lazy instance()

{

mut.WaitOne();

if (null == uniCounter)

{

uniCounter = new Counter_lazy();

}

mut.ReleaseMutex();

return uniCounter;

}

注意的是,本例中使用方法二要更改方法一的客戶程序,去掉Counter_lazy.intance()的注釋,並將Counter.intance()注釋。

singleton模式還可以拓展,只要稍加修改,就可以限制在某個應用中只能允許m個實例存在,而且為m個實例提供全局透明的訪問方法。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved