天天看點

一個單例模式引發的血案

今天下午去面試,二面面了有一個半小時,最後面試官說,你寫個代碼吧,你一定要注意各種文法啊,考慮效率啊,blabla...你寫個單例模式吧。

然後我就開始寫了。。。

然後寫了下面的代碼給面試官,然後說,多線程加鎖的代碼忘了具體是什麼了。。。

class Singleton {
private:
	static Singleton * volatile pInstance;
	Singleton(){}
public:
	Singleton* instance() {
		if (pInstance == 0) {
			Lock
			{
				if (pInstance == 0) {
					pInstance = new Singleton;
				}
			}
		}
		return pInstance;
	}
};
           

面試官看了半天說,嗯,就這樣吧。。。

然後本來就要結束了,面試官突然又來了句,你的代碼還有沒有什麼優化的?

我說,有!(因為我隐約記得看書的時候static對象可以寫成在需要類執行個體的時候再建立。)

在哪?

在static那!

面試官看了一眼,然後,一臉驚喜,你的程式有個大bug!bug!bug!!!!這裡少了一個static,然後blablabla....

不過,人家面試官分析的是對的。。。

面試官又補充了句,我給别人出這個題,都說不會,隻有你寫下來了,但是有個大bug!

你去找HR吧。

然後HR說,你可以回去了。。。

這就是一個單例模式引發的丢失一個offer的血案,具體點說,一個static丢失一個offer的血案!

丢失的static在這裡:static Singleton* instance() {

class Singleton {
private:
	static Singleton * volatile pInstance;
	Singleton(){}
public:
	static Singleton* instance() {
		if (pInstance == 0) {
			Lock
			{
				if (pInstance == 0) {
					pInstance = new Singleton;
				}
			}
		}
		return pInstance;
	}
 };
           

其他的單例模式的代碼一般都是用JAVA寫的,這樣:

public class Singleton {
    private static Singleton single;    //聲明靜态的單例對象的變量
    private Singleton() {}   //私有構造方法

    public static Singleton getSingle() {   //外部通過此方法可以擷取對象
        if (single == null) {
            synchronized (Singleton.class) {   //保證了同一時間隻能隻能有一個對象通路此同步塊
                if (single == null) {
                    single = new Singleton();
                }
            }
        }
        return single;   //傳回建立好的對象
    }
}
           

這些代碼都是雙檢鎖 Double-checked locking pattern

繼續閱讀