Android單例模式你應該知道到一切
阿新 • • 發佈:2019-01-30
前言
單例模式想必大家都使用過,但是也許你並不完全瞭解它,在這裡我就來詳細介紹一下所有的單例模式,及單例模式中涉及的一些細節問題。
一、單例模式的作用
保證了單利類的物件只有一個例項存在,利於協調系統整體的行為。
二、單利的模式的使用場景
確保某個類只有一個物件的場景,避免產生多個物件,消耗過多的資源,或者某種型別的物件應該只有一個。例如需要訪問IO和資料庫等資源時,就需要考慮使用單例模式。
三、單利模式的UML圖
角色介紹:
(1)Client:客戶端,即呼叫者
(2)Singleton:單例類
實現單利類需要注意關鍵點如下:
(1)建構函式不對外開放,一般為private
(2)通過一個靜態方法或者列舉返回單利類的物件
(3)確保單利類的物件有且只有一個,尤其是在多執行緒下。
(4)確保單利類的物件在返序列化的時候不會重新構建物件。
四、單例模式的種類
單例模式主要分為以下幾種
1)餓漢模式
/***
* 餓漢式
*
* 優點:多執行緒安全
* 缺點:提前載入記憶體,佔用記憶體。
*
*/
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
2)懶漢模式1
/***
* 懶漢式
*
* 優點:隨用隨載入
* 缺點:多執行緒是不安全的
*
*/
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
3)懶漢模式2
/***
* 懶漢式2:方法同步
*
* 優點:隨用隨載入,多執行緒安全
* 缺點:第一次載入時需要及時進行初始化,反應慢。且每次呼叫getInstance時都進行了同步,造成不必要的開銷
*
*/
private static Singleton instance = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
4)懶漢模式3
此種方法也是使用人數比較多的
/***
* 懶漢式3:Double Check Lock(DCL) 雙檢查鎖
*
* 優點:資源利用率高,隨用隨載入,多執行緒安全,2次判空,避免不必要的同步鎖,節省資源。
* 缺點:第一次載入反應稍慢
*
* PS:volatile的作用:由於JDK1.5之前,JVM對於類的載入機制的問題會導致失效,在1.5之後加上此關鍵字可以保證DCL單利不失效。
*
*/
private volatile static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null){
instance = new Singleton();
}
}
}
return instance;
}
5)靜態內部類的單利模式
此種單利模式,推薦使用,效果好。
/***
* 靜態內部類的單利模式:推薦使用的模式
*
* 優點:多執行緒安全,延遲載入
* 缺點:
*
*/
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
/***
* 靜態內部類
*/
private static class SingletonHolder{
private static final Singleton instance = new Singleton();
}
6)列舉的單利模式
/***
* 列舉的單例模式
*
* 優點:寫法簡單,列舉預設是執行緒安全,並且在任何情況下它都只有一個例項,支援反序列化。
* 缺點:
*
* PS:上面幾種單例模式在反序列化的時候都會生成新的物件,但是列舉不會。如果上面幾種方法要想反序列化
* 的時候也不生成新的例項就需要重寫 readResolve()方法,如下:
*
* private Object readResolve() throws ObjectStreamException{
* return instance;
* }
*
*/
public enum SingletonEnum{
INSTANCE;
}
7)使用容器實現單利模式
/***
* 使用容器實現單例模式
*
* 優點:將多種單利型別放在統一的管理類中,使用使根據key獲取單利物件。降低使用者使用成本,也對使用者隱藏了具體實現,降低耦合
* 缺點:
*
*/
public class SingletonManager{
private static Map<String,Object> objMap = new HashMap<>();
private SingletonManager(){}
public static void registerSingleton(String key,Object instance){
if (!objMap.containsKey(key)){
objMap.put(key,instance);
}
}
public static Object getSingleton(String key){
return objMap.get(key);
}
}
五、結語
不關以哪種方式實現的單利模式,他們的核心都是之前說到的4點
(1)建構函式不對外開放,一般為private
(2)通過一個靜態方法或者列舉返回單利類的物件
(3)確保單利類的物件有且只有一個,尤其是在多執行緒下。
(4)確保單利類的物件在返序列化的時候不會重新構建物件。
至於到底選擇哪種單例模式,試自己專案而定。
如有錯誤還請指出!(^o^)/~