軟體實現中,有些時候整個系統只需要擁有乙個全域性物件,這樣有利於協調系統的整體行為,使系統在單個物件存在時更有效率,或者限制例項化為特定數量的物件。例如對某個協議棧模組的訪問, 需要整個模組有且僅有乙個訪問入口,否則將會導致協議棧狀態混亂,為此需要實現建立管理乙個全域性管理物件,維持其生命週期。
在軟體工程中,單例模式提供了這樣乙個實現,保證了乙個類只有乙個例項存在,並提供乙個訪問它的全域性訪問點。
通過情況下,我們可以使用全域性變數使得乙個物件被全域性訪問,但該方法不能防止例項化多個物件,無法保證例項唯一性,乙個最好的辦法是,讓類自身負責保護它的唯一例項,這個類可以保證沒有其它例項被建立,並且提供乙個訪問該例項的方法,實現類例項的唯一性和受控訪問。
單例模式乙個經典的實現方式:
class singleton
singleton(const singleton&);
singleton& operator=(const singleton&);
private:
static singleton *m_pinstance;
public:
static singleton* getinstance() //本類例項全域性唯一訪問點
static
void destoryinstance()
} // other methods...
};
singleton class通過將類的建構函式、複製建構函式以及賦值函式限定為private,避免了類在外部被例項化,其唯一例項只能通過getinstance()方法訪問。
上述單例模式實現**直觀易懂,但沒有考慮執行緒安全問題,在多執行緒的執行環境中,當多個執行緒同時訪問singletion類的getinstance()方法時,極有可能造成建立多個例項。若執行緒a執行檢測到m_pinstance == null, 但來得及執行m_pinstance = new singleton()時被執行緒b中斷,執行緒b 執行同樣的判斷m_pinstance == null 從而建立了類的例項,當執行緒a再次獲得執行權時,將繼續執行建立類例項的操作,再次建立了例項,從而建立了多個例項,違背單例模式的初衷。因此比較直接的做法是,在建立例項時加鎖lock,lock 確保當執行緒a位於**lock保護區域時,其餘執行緒不能進入該lock保護區域,此時若其它執行緒試圖進入lock 保護區域,那麼它將一直被阻塞等待,直到鎖物件被釋放。
static singleton* getinstance() //本類例項全域性唯一訪問點
return m_pinstance;
}
這種實現方式的確保證了單例模式的執行緒安全,確保物件建立的唯一性,但每次呼叫getinstance 獲取物件都需要lock 後判斷, 對效能有較大影響, 一種改進的做法是,先判斷物件是否已經建立,在未建立的情況下再加鎖建立, 確保建立的唯一性。
static singleton getinstance() //本類例項全域性唯一訪問點
}return m_pinstance;
}
這種方式實現了在每次訪問getinstance 時僅僅在物件不存在時需要加鎖lock,大大提高了效率。
說明: 單例模式有多種實現方式,文中只實現了其中的一種,逐步分析提供了在多執行緒環境中的安全機制。
Java設計模式之單例模式(Singleton)
前言 在總結okhttp的時候,為了管理網路請求使用到了單例模式,晚上實在沒啥狀態了,靜下心來學習總結一下使用頻率最高的設計模式單例模式。單例模式 單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。單例特點 單例分類 1 懶漢單例 1 非執行緒安全實現 public class...
設計模式 建立型模式 單例模式 Singleton
4種單例模式 單執行緒單例 類class single private static single sin null public static single createinstance return sin 呼叫 console.writeline 單執行緒單例模式 single sin sin...
大話設計模式二十一 單例模式(Singleton)
一.單例模式定義 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。二.結構和說明 singleton負責建立singleton類自己的唯一例項,並提供乙個getinstance方法,讓外部來訪問這個類的唯一例項。三.呼叫示例圖 實現 四.控制例項個數 簡單演示如何擴充套件單例模式,控制例項數...