定義
應(yīng)用內(nèi)只存在類的一個實例
餓漢式
public class Singleton {
public static Singleton mInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return mInstance;
}
}
懶漢式
- 方案一
public class Singleton {
public static Singleton mInstance ;
private Singleton() {
}
public static Singleton getInstance(){
if (mInstance == null) {
mInstance = new Singleton();
}
return mInstance;
}
}
存在問題:多線程并發(fā)時脂信,可能new出多個對象
- 方案二
public class Singleton {
public static Singleton mInstance ;
private Singleton() {
}
public synchronized static Singleton getInstance(){
if (mInstance == null) {
mInstance = new Singleton();
}
return mInstance;
}
}
存在問題:多線程并發(fā)時癣蟋,每個線程都需要判斷一次同步鎖,效率較低
- 方案三(推薦)
public class Singleton {
public static Singleton mInstance ;
private Singleton() {
}
public static Singleton getInstance(){
if (mInstance == null) {
synchronized (Singleton.class){
if (mInstance == null) {
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
存在問題:存在不加關(guān)鍵字volatile的弊端
volatile的作用:
- 防止重排序( 1 分配一塊內(nèi)存空間 2 初始化對象(指向內(nèi)存空間) 3賦值
多線程時2,3可能會更換順序狰闪,出現(xiàn)意想不到的錯誤) - 線程可見(一個線程改變了公用對象疯搅,短時間內(nèi),可能對另一個線程不可見)
- 方案四(推薦)
public class Singleton {
public volatile static Singleton mInstance ;
private Singleton() {
}
public static Singleton getInstance(){
if (mInstance == null) {
synchronized (Singleton.class){
if (mInstance == null) {
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
靜態(tài)內(nèi)部類
public class Singleton {
public static Singleton mInstance;
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.mInstance;
}
static class SingletonHolder {
static Singleton mInstance = new Singleton();
}
}
容器管理
public class Singleton {
public static Map<String,Object> mSingleMap = new HashMap<>();
static {
mSingleMap.put("activity_manager",new Singleton());
}
private Singleton() {
}
public static Object getInstance(String name) {
return mSingleMap.get(name);
}
}