歡迎您光臨本站 註冊首頁

Java認證考試:關於Singleton模式的學習

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0
  學習設計模式,自然從最簡單的模式入手,而最簡單的模式便是Singleton.所以第一篇就來所以說Singleton模式.看完GOF和Design patterns in Java的書,感覺Singleton雖然簡單,但是想寫出一個好的Singleton也不是一上來就能寫出來的.
  Singleton模式的用處自然是保證一個類只有一個唯一的實例.在建模中涉及到的只能有一個對象,例如Struts中的Action類就是一例.除此之外,Singleton還是的該對象只有一個全局訪問點.這就是SIngleton的作用.
  說得比較抽象,我們來看一個簡單Singleton的C 和Java的代碼:
  C Singleton模式:
  類定義:
  1.class Singleton
  2.{
  3.public:
  4. static Singleton * Instance();
  5. ~Singleton();
  6.
  7.private:
  8. Singleton();
  9.
  10. static Singleton * instance;
  11.};
  方法實現:
  12.Singleton * Singleton::instance = 0;
  13.
  14.Singleton::Singleton()
  15.{
  16.
  17.}
  18.
  19.Singleton::~Singleton()
  20.{
  21.
  22.}
  23.
  24.Singleton * Singleton::Instance()
  25.{
  26. if (instance == 0) {
  27. instance = new Singleton();
  28. }
  29.
  30. return instance;
  31.}
  Java Singleton模式:
  32.public class Singleton {
  33.
  34. private static Singleton instance;
  35.
  36. public static Singleton getInstance() {
  37. if (instance == null)
  38. instance = new Singleton();
  39.
  40. return instance;
  41. }
  42.
  43. /** *//** Creates a new instance of Singleton */
  44. private Singleton() {
  45. }
  46.}
  通過上面的例子可以看出,Singleton的實現並不難,只要將構造函數訪問域設為私有,然後添加一個靜態引用和一個獲得該應用的靜態方法即可.其實在C 中定義一個全局靜態變數也可以達到這個效果,但是像Java這樣的語言就是能使用Singleton了.
  上面的程序有一個問題,就是只能運行在單線程的環境下.為此我在C 上作了個實驗.#include .在SIngleton::Instance()函數中增加一個Sleep(1000),程序如下:
  47.Singleton * Singleton::Instance()
  48.{
  49. if (instance == 0) {
  50. Sleep(1000);
  51. instance = new Singleton();
  52. }
  53.
  54. return instance;
  55.}
  然後在主函數中創建兩個線程,程序如下:
  56.static Singleton * s1 = 0, * s2 = 0;
  57.
  58.DWORD WINAPI ThreadProc1(PVOID)


  59.{
  60. s1 = Singleton::Instance();
  61.
  62. return 0;
  63.}
  64.
  65.DWORD WINAPI ThreadProc2(PVOID)
  66.{
  67. s2 = Singleton::Instance();
  68.
  69. return 0;
  70.}
  71.
  72.int main(int argc, char* argv[])
  73.{
  74. DWORD threadID1;
  75. DWORD threadID2;
  76.
  77. CreateThread(NULL, 0, ThreadProc1, NULL, 0, &threadID1);
  78. CreateThread(NULL, 0, ThreadProc2, NULL, 0, &threadID2);
  79.
  80. Sleep(10000);
  81.
  82. std::cout << s1 << " " << s2;
  83.
  84. return 0;
  85.}
  這樣修改後在運行程序,列印出來的s1和s2地址就不是同一個地址了.結果如下:
  0372D68 00372E68Press any key to continue
  可見當在多線程環境下使用這個Singleton就會出現創建不止一個實力的情況,所以我們需要給Singleton加鎖.請看下面的代碼.
  C Singleton模式:
  86.class Singleton
  87.{
  88.public:
  89. static Singleton * Instance();
  90. virtual ~Singleton();
  91.
  92.private:
  93. Singleton();
  94.
  95. static CMutex mutex;
  96. static Singleton * instance;
  97.};
  98.Singleton * Singleton::instance = 0;
  99.CMutex Singleton::mutex;
  100.
  101.Singleton::Singleton()
  102.{
  103.
  104.}
  105.
  106.Singleton::~Singleton()
  107.{
  108.
  109.}
  110.
  111.Singleton * Singleton::Instance()
  112.{
  113. mutex.Lock();
  114.
  115. if (instance == 0) {
  116. Sleep(1000);
  117. instance = new Singleton();
  118. }
  119.
  120. mutex.Unlock();
  121.
  122. return instance;
  123.}
  此外需要#include < afxmt.h>,,並且在項目設置中要設置動態鏈接MFC庫.
  Java Singleton模式:
  124.public class Singleton {
  125.
  126. private static Singleton instance;
  127. private static Object lock = Singleton.class;
  128.
  129. public static Singleton getInstance() {
  130. synchronized (lock) {
  131. if (instance == null)
  132. instance = new Singleton();
  133.
  134. return instance;
  135. }
  136. }
  137.
  138. /** *//** Creates a new instance of Singleton */
  139. private Singleton() {
  140. }
  141.}
  運用加鎖就可以解決在多線程環境下使用Singleton模式所帶來的問題了.


  


[火星人 ] Java認證考試:關於Singleton模式的學習已經有387次圍觀

http://coctec.com/docs/java/show-post-59944.html