單例模式的幾種方式:餓漢式單例,懶漢單例,雙層校驗鎖單例,容器單例,靜態內部類單例,列舉單例。
餓漢單例
/**
* 餓漢單例(類載入的時候就獲取例項)
* 執行緒安全的
*/public class singleton
public static singleton getinstance()
}
懶漢單例/**
* 懶漢單例(非執行緒安全)
*/public class singleton
public static singleton getinstance()
return instance;
}}
/**
* 懶漢單例(執行緒安全)
*/public class singleton
public static synchronized singleton getinstance()
return instance;
}}
在方法上加同步鎖使得執行緒安全,但多執行緒訪問方法每次都要等待鎖的釋放,這種方式效能太差。其實只需要在第一次例項化加鎖就可以了,之後訪問直接獲取例項就好了。所以出現了雙重檢驗鎖單例模式。
雙重校驗鎖單例
/**
* 雙重檢驗鎖單例(執行緒安全)
*/public class singleton
public static singleton getinstance()}}
return instance;
}}
1.第乙個if 判斷是否已經例項化,如果例項化則直接返回,不需要在執行同步鎖,優化了效能。
2.第二個 if,多個執行緒通過第乙個 if判斷,其中乙個執行緒先獲得鎖並例項化物件,當第乙個執行緒釋放鎖後,之後獲得鎖的執行緒不會在例項化物件,直接返回例項。
這種方式仍然存在隱患,物件例項化分三個步驟:
1.分配記憶體空間
2.初始化物件
3.將物件指向剛分配的記憶體空間
編譯器為了效能可能將2和3的順序重排序:
1.分配記憶體空間
2.將物件指向剛分配的記憶體空間
3.初始化物件
a執行緒執行到2步驟時instance 不為空,b執行緒判斷到 instance 不為空,直接返回 instance,但是此時 instance 還未被初始化。使用volatile關鍵字解決問題,禁止重排,所有的寫(write)操作都將發生在讀(read)操作之前。
public class singleton
public static singleton getinstance()}}
return instance;
}}
容器單例/**
* 容器單例
*/public class singleton
public static void registerservice(string key,object instance)
}public static object getservice(string key)
}
靜態內部類單例public class singleton
}private singleton(){}
public static singleton getinstance()
}
列舉單例public enum singleton
public singleton1 getinstance()
}public class singleton1
}
java設計模式之單例模式
單位面試題目中有一道關於單例模式的題目.大多數參加筆試的同事都會寫出getinstance這個函式,但是當我問起什麼情況下需要使用單例 單例具體有什麼好處的時候 static函式也可以構建唯一例項,為什麼還需要單例.從使用單例的經驗來看,如下場景下,個人感覺應該使用單例 1.如果需要構建乙個工具類,...
java設計模式 之 單例模式
單例模式 有些類在程式執行過程中只需要儲存乙個例項,比如檔案管理類,音訊管理類,那麼我們如何實現乙個單例類呢?有以下幾點 1 定義乙個靜態變數 2 建構函式私有化 3 提供乙個public 靜態方法,獲取這個例項 4 一定要做執行緒同步 public static class singleton p...
Java設計模式之單例模式
說到單例模式 大家一定非常熟悉 這是最常見也是設計模式中相對簡單 好理解的設計模式 今天就跟大家掰一掰單例模式 單例模式確保某個類只有乙個例項 應用場景 執行緒池 快取 等物件常常被設計成單例 然而單例分兩種 1 惡漢式 2 懶漢式 我們先來看下 惡漢式 public class singleton...