一、單例模式的特點:
1.單例模式有且只有一個實例;
2.單例模式必須自己創建自己的唯一實例;
3.單例模式必須向其他對象提供這一實例;(對外提供獲取唯一實例的方法)
二、單例模式的優點:
避免實例對象的重複創建,減少創建對象時的時間開銷,節約內存空間;
三、常見單例模式寫法:
1.餓漢式
public class Singleton{
private static Singleton st = new Singleton();
private Singleton() {};
public static Singleton getInstance() {
return st;
}
}
餓漢式顧名思義,每次一用它就直接創建了實例,優點是不存在多線程訪問的安全問題,缺點是這個實例在程序生命週期中都一直存在,對於內存資源的佔用較高;
2.懶漢式
public class Singleton{
private static Singleton st = null;
private Singleton() {};
public static Singleton getInstance() {
if(null == st) {
st = new Singleton();
}
return st;
}
}
懶漢式比餓漢式的優點是實現了懶加載,在具體需要的時候纔去實例化;
缺點是線程是不安全的,適用於單線程操作中;
3.懶漢式(線程安全,同步鎖synchronized)
public class Singleton{
private static Singleton st = null;
private Singleton() {};
public synchronized static Singleton getInstance() {
if(null == st) {
st = new Singleton();
}
return st;
}
}
優點:既實現了懶加載,又實現了線程安全;
缺點:性能較低,加鎖的方法在被調用時,比一般方法的調用要慢很多,這樣寫對於性能的損耗較高;
4.懶漢式(線程安全,雙重校驗鎖)
public class Singleton {
private static Singleton st = null;
private Singleton() {
};
public static Singleton getInstance() {
if (st == null) {
synchronized (Singleton.class) {
if (st == null) {
st = new Singleton();
}
}
}
return st;
}
}
5.靜態內部類
public class Singleton{
private static class SingletonHolder{
public static Singleton instance = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
這種方法是內部類裏創建實例,但是因爲內部類是private私有的,所以只有在調用到私有的內部類的時候,JVM纔會去創建實例對象;並且因爲寫在內部類裏,利用了類加載機制,不存在多線程併發的問題;
如果需要考慮線程安全問題,推薦使用第4或第5種。
最後是對自己說的話:單例模式是一種設計思想,很多時候我們很隨意的就會new一個對象,而不會去考慮是否需要用單例去實例化,我覺得比掌握幾種單例模式寫法更重要的是隨時考慮性能問題,更多地將單例模式運用到代碼中。