首先說明:「singleton」是乙個單詞,不是乙個複合詞。
接下來步入正題。對於單例模式無論是「餓漢」還是「懶漢」都必須要有的是:
一.私有建構函式
二.宣告靜態單例物件
如果是「懶漢」的話為了寫出好的沒有 bug的單例**還應注意
三.構造單例物件之前要加鎖(lock乙個靜態的object物件)
四.需要兩次檢測單例例項是否已經被構造,分別在鎖之前和鎖之後
/*方法一:實現singleton模式常規方法*/
class singleton //關鍵點0:建構函式私有
static singleton *p; //關鍵點1:宣告單例物件是靜態的
public:
static singleton * instance();
};singleton * singleton::instance()
singleton * singleton::p=null; //注意!
分析:這段**在通常情況下是可以執行的。但是遇到多執行緒可能就不行了。考慮兩個執行緒同時呼叫
instance
方法且同時檢測到p為
null
,顯然此時就不是單例了。
既然說到了多執行緒,顯然能想到加鎖來處理。於是有:
//方法二:在常規常規方法基礎上加鎖
class singleton
static singleton *p; //關鍵點1:宣告單例物件是靜態的
public:
static pthread_mutex_t mutex; //建立乙個互斥鎖
static singleton *instance();
};singleton *singleton::instance()
return p;
}singleton* singleton::p = null;
pthread_mutex_t singleton::mutex;
分析:由於延遲載入或者快取的原因,一次判斷仍然不能保證只建立乙個單例。於是乎有下面雙重檢查鎖定模式。
//方法三:雙重檢查鎖定模式
class singleton
static singleton *p; //關鍵點1:宣告單例物件是靜態的
public:
static pthread_mutex_t mutex; //建立乙個互斥鎖
static singleton *instance();
};singleton *singleton::instance()
pthread_mutex_unlock(&mutex); //解鎖
} return p;
}singleton* singleton::p = null;
pthread_mutex_t singleton::mutex;
分析:至此**就能確保單例,是可以接受的。但是這樣的**實現起來比較複雜,容易出錯。
於是引出了「懶漢模式」和「餓漢模式」。
懶漢:萬不得已才例項化類。延時載入
——以時間換空間。
餓漢:一上來就把物件給
new出來。非延時載入
——以空間換時間
顯然上面的**都是「懶漢模式」,那嫩否給出乙個「餓漢模式」的例子呢?當然
//方法4:餓漢模式_這樣所也不用加了。
/*人家還沒要,自己就忍不住的先準備好了,如飢似渴,所以叫餓漢模式*/
class singleton //關鍵點0:建構函式私有。
static singleton* p; //關鍵點1:宣告靜態單例物件是
public:
static singleton* instance()
};singleton* singleton::p=new singleton(); //關鍵點2:直接先建立了。
分析:**非常短,效果非常好,連鎖都不用了。
其實只要記住後面兩個實現就可以了。如果更注重空間效能就選擇「雙重檢查鎖定」,如果更注重時間效能則果斷選擇「餓漢模式」。
單例模式幾種實現
1.單執行緒模式下,推薦懶載入 public class singleton1 public static singleton1 getinstance return singleton 2.上述1演示,執行緒不安全,最容易想到的變為執行緒安全的方式就是加關鍵字synchronized public...
單例模式的幾種實現
1 餓漢式 執行緒安全,呼叫效率高,但是不能延時載入 public class imageloader public static imageloader getinstance 一上來就把單例物件建立出來了,要用的時候直接返回即可,這種可以說是單例模式中最簡單的一種實現方式。但是問題也比較明顯。單...
單例模式的幾種實現
單例模式,是設計模式之一,目的是為了只提供乙個物件,單例模式的實現,一般需要滿足 1 構造器私有 2 提供乙個共有的外界訪問例項的方法 以下提供單例模式的幾種實現方式 單例 餓漢式 public class eagersingleton 獲取例項的公共方法 public static eagersi...