設計模式-單例模式 Singleton
阿新 • • 發佈:2018-11-30
1 好處
- 1、 避免例項物件的重複建立,節約記憶體空間
- 2、 能夠避免由於操作多個例項導致的邏輯錯誤
例子
- 1、 正常的new物件
Singleton ns = new Singleton();
System.out.println("---new Singleton()>:"+ns);
Singleton ns2 = new Singleton();
System.out.println("---new Singleton()2>:"+ns2);
- 列印結果 兩個不同的記憶體地址
---new Singleton()>:com .qz.hesvit.planmode.Singleton@4a744a4d
---new Singleton()2>:com.qz.hesvit.planmode.Singleton@18ba2b6b
- 2、 惡漢式
public class Singleton {
// 一定要private修改構造方法,單例不能直接new物件
private Singleton() {
}
//惡漢模式
//在自己內部定義一個自己的例項,只供自己呼叫
private static final Singleton singleton = new Singleton();
public static Singleton getInstance() {
return singleton;
}
}
- 測試和列印結果 相同的記憶體地址
Singleton s = Singleton.getInstance();
System.out.println("sss---"+s);
Singleton s2 = Singleton.getInstance();
System.out.println("sss2--"+s2);
//列印結果
sss---com.qz.hesvit.planmode.Singleton@4a744a4d
sss2--com .qz.hesvit.planmode.Singleton@4a744a4d
- 3、 懶漢式
public class Singleton {
// 一定要private修改構造方法,單例不能直接new物件
private Singleton() {
}
// 懶漢模式中單例是在需要的時候才去建立的
private static Singleton singleton = null;
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
//但是這裡的懶漢模式並沒有考慮執行緒安全問題,在多個執行緒可能會併發呼叫它的
//getInstance()方法,導致建立多個例項,因此需要加鎖解決執行緒同步問題,實現如下:
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
- 測試和列印結果 相同的記憶體地址
Singleton s = Singleton.getInstance();
System.out.println("sss---"+s);
Singleton s2 = Singleton.getInstance();
System.out.println("sss2--"+s2);
//列印結果
sss---com.qz.hesvit.planmode.Singleton@4a744a4d
sss2--com.qz.hesvit.planmode.Singleton@4a744a4d
- 4、 雙重加鎖
public class Singleton {
// 一定要private修改構造方法,單例不能直接new物件
private Singleton() {
}
//雙重加鎖
/*
加鎖的懶漢模式看起來即解決了執行緒併發問題,又實現了延遲載入,然而它存在著效能問題,
依然不夠完美。synchronized修飾的同步方法比一般方法要慢很多,
如果多次呼叫getInstance(),累積的效能損耗就比較大了。
因此就有了雙重校驗鎖,先看下它的實現程式碼。
*/
private static Singleton singleton = null;
public static Singleton getInstance() {
if(null == singleton) {
synchronized(Singleton.class) {
if (singleton == null) { //2重加鎖
singleton = new Singleton();
}
return singleton;
}
}
}
}
- 測試和列印結果 相同的記憶體地址
Singleton s = Singleton.getInstance();
System.out.println("sss---"+s);
Singleton s2 = Singleton.getInstance();
System.out.println("sss2--"+s2);
//列印結果
sss---com.qz.hesvit.planmode.Singleton@4a744a4d
sss2--com.qz.hesvit.planmode.Singleton@4a744a4d