国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 建站經驗 > 正文

asp.net中C++單例實現、問題分析

2019-11-02 14:46:05
字體:
來源:轉載
供稿:網友

   方案一

 代碼如下   class QMManager
{
public:
    static QMManager &instance()
    {
        static QMManager instance_;
        return instance_;
    }
}

  這是最簡單的版本,在單線程下(或者是C++0X下)是沒任何問題的,但在多線程下就不行了,因為static QMManager instance_;這句話不是線程安全的。

  在局部作用域下的靜態變量在編譯時,編譯器會創建一個附加變量標識靜態變量是否被初始化,會被編譯器變成像下面這樣(偽代碼):

 代碼如下   static QMManager &instance()
{
    static bool constructed = false;
    static uninitialized QMManager instance_;
    if (!constructed) {
        constructed = true;
        new(&s) QMManager; //construct it
    }
    return instance_;
}

  這里有競爭條件,兩個線程同時調用instance()時,一個線程運行到if語句進入后還沒設constructed值,此時切換到另一線程,constructed值還是false,同樣進入到if語句里初始化變量,兩個線程都執行了這個單例類的初始化,就不再是單例了。

  方案二

  一個解決方法是加鎖:

 代碼如下   static QMManager &instance()
{
    Lock(); //鎖自己實現
    static QMManager instance_;
    UnLock();
    return instance_;
}

  但這樣每次調用instance()都要加鎖解鎖,代價略大。

  方案三

  那再改變一下,把內部靜態實例變成類的靜態成員,在外部初始化,也就是在include了文件,main函數執行前就初始化這個實例,就不會有線程重入問題了:

 代碼如下   class QMManager
{
protected:
    static QMManager instance_;
    QMManager();
    ~QMManager(){};
public:
    static QMManager *instance()
    {
        return &instance_;
    }
    void do_something();
};
QMManager QMManager::instance_; //外部初始化

  這被稱為餓漢模式,程序一加載就初始化,不管有沒有調用到。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 张家川| 馆陶县| 福泉市| 沧源| 交城县| 湟源县| 横峰县| 浑源县| 阳西县| 开江县| 洛南县| 界首市| 通化市| 北辰区| 克山县| 肃宁县| 阳信县| 林甸县| 南阳市| 河北区| 西乌珠穆沁旗| 北川| 松滋市| 丁青县| 金华市| 从江县| 麻阳| 疏勒县| 乌兰县| 通辽市| 临漳县| 南部县| 芒康县| 萝北县| 榆林市| 逊克县| 新丰县| 雷波县| 沐川县| 驻马店市| 贵港市|