方案一
代碼如下 class QMManager這是最簡單的版本,在單線程下(或者是C++0X下)是沒任何問題的,但在多線程下就不行了,因為static QMManager instance_;這句話不是線程安全的。
在局部作用域下的靜態變量在編譯時,編譯器會創建一個附加變量標識靜態變量是否被初始化,會被編譯器變成像下面這樣(偽代碼):
代碼如下 static QMManager &instance()這里有競爭條件,兩個線程同時調用instance()時,一個線程運行到if語句進入后還沒設constructed值,此時切換到另一線程,constructed值還是false,同樣進入到if語句里初始化變量,兩個線程都執行了這個單例類的初始化,就不再是單例了。
方案二
一個解決方法是加鎖:
代碼如下 static QMManager &instance()但這樣每次調用instance()都要加鎖解鎖,代價略大。
方案三
那再改變一下,把內部靜態實例變成類的靜態成員,在外部初始化,也就是在include了文件,main函數執行前就初始化這個實例,就不會有線程重入問題了:
代碼如下 class QMManager這被稱為餓漢模式,程序一加載就初始化,不管有沒有調用到。
新聞熱點
疑難解答