單例模式的實現方式有懶漢,餓漢,雙重校驗鎖,枚舉,內部類等等,寫法就不全部列舉了。Android源碼中一個單例輔助類/frameworks/base/core/java/android/util/Singleton.java,可以實現懶漢式單例,寫法挺奇特的,雖然是個hide類,不過拷貝出來就可以用了。
package android.util;
/**
* Singleton helper class for lazily initialization.
*
* Modeled after frameworks/base/include/utils/Singleton.h
*
* @hide
*/
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
正常懶漢單例
public class SingletonDemo {
private static SingletonDemo mInstance;
public static final SingletonDemo get() {
synchronized (SingletonDemo.class) {
if (mInstance == null) {
mInstance = new SingletonDemo();
}
return mInstance;
}
}
}
懶漢+雙重校驗單例
public class SingletonDemo {
private static SingletonDemo mInstance;
public static final SingletonDemo get() {
if (mInstance == null) {
synchronized (SingletonDemo.class) {
if (mInstance == null) {
mInstance = new SingletonDemo();
}
}
}
return mInstance;
}
}
變種懶漢單例
public class SingletonDemo {
public static final SingletonDemo get() {
return INSTANCE.get();
}
private static final Singleton<SingletonDemo> INSTANCE = new Singleton<SingletonDemo>() {
protected SingletonDemo create() {
return new SingletonDemo();
}
};
}
懶漢式單例一般都會再加個雙重校驗的判斷,避免每次調用get()都加鎖,影響性能,Android源碼中Singleton.java工具類並沒有做雙重校驗(看了下googlesource中的Singleton.java,也是6年前提交的代碼了),所以我們在將Singleton.java拷貝出來使用的時候可以加個雙重校驗優化下。Singleton.java封裝了create,get模版,及get中的校驗邏輯,從而SingletonDemo中的實現代碼就可以更加的簡單:1.create()一個單例對象,2.在需要的時候get()。