簡介
單例模式是指在程式中只有乙個例項存在。並且在程式執行中的任何時候都可以獲取該例項物件。
場景
1.android中資料庫多執行緒讀寫時,保證每個執行緒使用同乙個sqlitedatabase物件,否則會報錯「database is locked」;
2.android常用框架eventbus中使用了單例模式。例如,當我們獲取eventbus物件時,會使用的eventbus.getdefault(),當我們檢視它的原始碼的時候,我們發現
static volatile eventbus defaultinstance;
...//此處省略
...public static eventbus getdefault() }}
return defaultinstance;
}
也就是eventbus使用了雙重校驗鎖的單例模式。此模式稍候介紹。
單例模式的實現方式
1.懶漢模式
特點:懶載入,不使用不建立,執行緒不安全
public class singleton
public static singleton getinstance()
}
2.餓漢模式
特點:類載入的時候就建立物件,執行緒安全,沒有懶載入的靈活性,可能造成記憶體浪費
public class singleton
public static singleton getinstance()
}
3.雙重校驗鎖
特點:可以保證執行緒安全,但是需要使用volatile(jdk1.5引入)修飾物件的引用,因為只是使用雙重校驗鎖時,也不能保證它是乙個執行緒安全的單例模式。因為jmm會有指令重排序機制。當我們建立乙個物件的時候,jvm內部會將new object()這條語句轉化為若干指令,舉例:
指令1:先為物件分配記憶體空間
指令2:初始化物件
指令3:設定物件所在的記憶體位址
以上是正常情況,如果發生了指令重排,可能指令3就會排在指令2的前面。
也就是先分配了記憶體位址,後初始化的物件。如果這時執行緒a指令執行的順序是1-3-2,那麼,當執行緒a執行到指令3的時候,msingleton不為null了。如果執行緒b執行到第乙個if判斷的時候,發現msingleton不為空,這時就會出現問題。(見下面**)
public class singleton
public singleton getinstance()
}return msingleton;
}}
使用volatile關鍵字後,就可以禁止指令重排序(增加了記憶體屏障)
正確**:
public class singleton
public singleton getinstance()
}return msingleton;
}}
4.靜態內部類
特點:類載入的時候就建立物件(此特點跟餓漢模式一樣),執行緒安全;懶載入,不使用不建立,減少記憶體開銷。
public class singleton
private static class singleinstance
public static final singleton getinstance()
}
5.列舉單例模式
特點:執行緒安全,防止了反序列化重新建立的新物件
public enum emumsingleton
public void dosomething()
}
over… 單例模式(5種實現方式)
1.餓漢式 不支援併發 此模式只能執行在單執行緒下,且類在載入時就已經建立好了例項,不管需不需要用。package com.lys 餓漢式 public class singleton1 private static singleton1 instance new singleton1 public...
5種方式實現單例模式
破壞單例模式的方法及應對 使用場景 單例模式的核心是乙個類只允許有乙個例項化物件。spring物件池預設就是單例模式。如果生產環境下某類只需要也只允許有乙個例項化物件就可以考慮使用單例模式。實現單例模式的策略是 構造方法私有化,也就是外部不允許通過new的方式獲取物件,而是提供乙個公開的靜態方法供外...
單例模式 5種實現方式
單例模式能夠保證乙個類僅有唯一的例項,並提供乙個全域性訪問點。1 餓漢式 執行緒安全,呼叫效率高,但是不能延時載入 public class singleton public static singleton getinstance 2.懶漢式 執行緒安全,呼叫效率不高,但是能延時載入 public...