單例模式

單例模式:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。
單例模式分為懶漢式餓漢式

懶漢式是當該實例第一次被引用時,才將自己實例化;
餓漢式是在被加載時就將自己實例化了。

懶漢式

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    if(instance == NULL)
        instance = new Singleton();
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

懶漢式是線程不安全的,當單例模式應用在多線程中,應該使用鎖進行同步

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    if(instance == NULL) {
        lock();
        if(instance == NULL)
            instance = new Singleton();
        unlock();
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

而餓漢式是線程安全的

class Singleton{
public:
    static Singleton* getInstance();
    void doSomething();
    void destroy();
    
private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Singleton* instance;
};
Singleton* Singleton::instance = new Singleton();
Singleton::Singleton() {}
Singleton::~Singleton() {}
Singleton* Singleton::getInstance() {
    return instance;
}
void Singleton::destroy() {
    delete this;
    instance = NULL;
}
int main() {
    Singleton::getInstance()->doSomething();
    Singleton::getInstance()->destroy();
    return 0;
}

優缺點

餓漢式
優點
1. 線程安全
2. 在類加載的同時已經創建好一個靜態對象,調用時反應速度快
缺點
資源效率不高,可能getInstance()永遠不會執行到,但執行該類的其他靜態方法,那么這個實例仍然初始化

懶漢式
優點:
避免了餓漢式的那種在沒有用到的情況下創建事例,資源利用率高,不執行getInstance()就不會被實例,可以執行該類的其他靜態方法。
缺點:
不是線程安全,在多線程中需要線程同步,同步加鎖的過程提高了系統的開銷

應用場景

  1. 網站的計數器,一般也是采用單例模式實現,否則難以同步。
  2. 應用程序的日志應用,一般都何用單例模式實現,這一般是由于共享的日志文件一直處于打開狀態,因為只能有一個實例去操作,否則內容不好追加。
  3. Web應用的配置對象的讀取,一般也應用單例模式,這個是由于配置文件是共享的資源。
  4. 數據庫連接池的設計一般也是采用單例模式,因為數據庫連接是一種數據庫資源。數據庫軟件系統中使用數據庫連接池,主要是節省打開或者關閉數據庫連接所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因為何用單例模式來維護,就可以大大降低這種損耗。
  5. 多線程的線程池的設計一般也是采用單例模式,這是由于線程池要方便對池中的線程進行控制。
  6. 操作系統的文件系統,也是大的單例模式實現的具體例子,一個操作系統只能有一個文件系統。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容