單例模式 - 雙鎖機制

目錄

1 餓漢模式

2 懶漢模式

3 多線程安全的懶漢單例模式

3.1 普通加鎖方式

3.2 雙鎖機制


1 餓漢模式

在程序啓動或單件模式類被加載的時候,單件模式實例就已經被創建。

主要注意如下四個部分:

  • 構造函數私有化或者保護化
  • .禁止拷貝和賦值
  • 靜態的共有接口
  • 初始化靜態數據成員

懶漢模式

當程序第一次訪問單件模式實例時才進行創建。

       懶漢模式下,在定義m_instance變量時先等於NULL,在調用GetInstance()方法時,在判斷是否要賦值。這種模式,並非是線程安全的,因爲多個線程同時調用GetInstance()方法,就可能導致有產生多個實例。要實現線程安全,就必須加鎖

多線程安全的懶漢單例模式

3.1 普通加鎖方式

      這種GetInstance()方法,每次進來都要加鎖,會影響效率。然而這並不是必須的,於是又對GetInstance()方法進行改進。

3.2 雙鎖機制

        上述的方式可能會有意料不到的後果。問題的來源是CPU的亂序執行,C++的New操作實際上包含了兩個步驟:(1)分配內存;(2)調用構造函數

實際上,m_instance = new T()包含了三個步驟:

  1. 分配內存
  2. 在內存的位置上調用構造函數
  3. 將內存的地址賦值給pInst

          因爲(2)和(3)是可以顛倒的,所以可以出現這樣的情況:m_instance的值已經不是NULL,但對象仍然沒有構造完畢。如果另外一個線程對GetInstance的調用,此時第一個if爲false,這樣就會返回一個未構造完成的對象,此時可能會導致程序崩潰
 

解決思路:用一個局部變量過渡下就ok了

       在linux提供了一個叫pthread_once()的函數,它保證在一個進程中,某個函數只被執行一次。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章