設計模式:單例模式(至少有一種你沒有見過)

背景

本文中的例子可能是從《clr via c#》中抄襲而來,讀過這本書最後一章的朋友,應該見過各類實現了。c#

各類實現

第一種:簡單版本

代碼設計模式

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace DesignPatternStudy.Creations.Singletons
 8 {
 9     class SimpleSingleton
10     {
11         private static readonly SimpleSingleton _instance;
12 
13         private SimpleSingleton() { }
14 
15         static SimpleSingleton()
16         {
17             _instance = new SimpleSingleton();
18         }
19 
20         public static SimpleSingleton Singleton
21         {
22             get
23             {
24                 return _instance;
25             }
26         }
27     }
28 }

說明:靜態構造方法是線程安全的,所以能夠保證單例。若是單例類型有其它靜態方法,調用這些方法會致使單例被初始化。安全

第二種:嵌套類

代碼spa

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace DesignPatternStudy.Creations.Singletons
 8 {
 9     class NestedSingleton
10     {
11         private NestedSingleton() { }
12 
13         public static NestedSingleton Singleton
14         {
15             get
16             {
17                 return Nested._instance;
18             }
19         }
20 
21         public static void OtherStaticMethod()
22         {
23             Console.WriteLine("不會產生單例!");
24         }
25 
26         private class Nested
27         {
28             public static readonly NestedSingleton _instance;
29 
30             static Nested()
31             {
32                 _instance = new NestedSingleton();
33             }
34         }
35     }
36 }

說明:解決了「簡單版本」的問題,調用單例類型的靜態方法不會致使單例被實例化。線程

第三種:雙校驗+悲觀鎖

代碼設計

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace DesignPatternStudy.Creations.Singletons
 8 {
 9     class DoubleCheckSingleton
10     {
11         private static readonly Object _lock = new Object();
12         private static DoubleCheckSingleton _instance;
13 
14         private DoubleCheckSingleton() { }
15 
16         public static DoubleCheckSingleton Singleton
17         {
18             get
19             {
20                 if (_instance != null)
21                 {
22                     return _instance;
23                 }
24 
25                 lock (_lock)
26                 {
27                     if (_instance == null)
28                     {
29                         _instance = new DoubleCheckSingleton();
30                     }
31                 }
32 
33                 return _instance;
34             }
35         }
36     }
37 }

說明:設計模式的做者使用的語言是 C++,C++ 沒有和 C# 靜態構造方法一樣語義的機制,所以使用了這種雙校驗機制。code

第四種:雙校驗+樂觀鎖

代碼blog

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Threading;
 7 
 8 namespace DesignPatternStudy.Creations.Singletons
 9 {
10     class CASSingleton
11     {
12         private static CASSingleton _instance;
13 
14         private CASSingleton()
15         {
16             Console.WriteLine("CASSingleton");
17         }
18 
19         public static CASSingleton Singleton
20         {
21             get
22             {
23                 if (_instance != null)
24                 {
25                     return _instance;
26                 }
27 
28                 Interlocked.CompareExchange(ref _instance, new CASSingleton(), null);  // 至關於:update xxx_table set version = new_version where version = old_version
29 
30                 return _instance;
31             }
32         }
33     }
34 }

說明:樂觀鎖在某些狀況下是比悲觀鎖好用,在本例中有一點要求:構造方法的執行必須沒有反作用,由於內部可能建立多個實例,外部只會看到一個。get

備註

看完大師的書籍,以爲本身好眇小,繼續努力吧。it

相關文章
相關標籤/搜索