1、什麼是單例模式?
單例模式是一種對象創建模式,使用單例模式,可以保證爲一個類只生成唯一的實例對象。
也就是說,在整個程序空間,該類只存在一個對象。
Gof對單例模式的定義是:保證一個類,只有一個實例存在,同時提供能對該實例加以訪問的全局方法。
2、爲什麼要使用單例模式?
在應用系統開發中,我們常常有以下要求:
1、在多個線程之間,比如servlet環境,共享同一個資源或者操作同一個對象
2、在整個程序空間使用全局變量,共享資源
3、大規模系統中,爲了性能的考慮,需要節省對象創建時間等等。
因爲Sinleton模式可以保證爲一個類只生成唯一的實例對象,所以這些,Singleton模式就派上用場了。
3、單例模式的創建方式
1、懶漢式
2、餓漢式
3、雙重檢查模式’
4、代碼實現分析
1、普通對象創建
package com.sinwao.singleton;
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、懶漢式創建單例
package com.sinwao.singleton;
public class LazyPerson {
public static final LazyPerson hp = new LazyPerson();
private LazyPerson() {}
public static LazyPerson getInstance() {
return hp;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
該模式線程始終是安全,但是比較消耗內存資源3、餓漢式創建單例
package com.sinwao.singleton;
public class HungryPerson {
public static HungryPerson lp = null;
private HungryPerson() {}
public static HungryPerson getInstance() {
if (lp == null) {
lp = new HungryPerson();
}
return lp;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
該模式在多線程訪問同一對象時,可能會出現重複創建對象,於是又了雙重檢查機制
4、雙重檢查創建單例
package com.sinwao.singleton;
public class DoubleCheckPerson {
public static DoubleCheckPerson dcp = null;
private DoubleCheckPerson() {}
public static DoubleCheckPerson getInstance() {
if (dcp == null) {
synchronized (DoubleCheckPerson.class) {
if (dcp == null) {
dcp = new DoubleCheckPerson();
}
}
}
return dcp;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
該模式線程是安全的,在多線程情況下也不會出現重複創建對象的情況,效率較高,內存開銷也較低。注意一點:面試的時候我也被問到過這種情況
5、測試
package com.sinwao.singleton;
/**
* 單例模式
* @author Administrator
*
*/
public class TestSingleton {
public static void main(String[] args) {
System.out.println("一般對象創建");
Person p1 = new Person();
Person p2 = new Person();
p1.setName("T-Mac");
p2.setName("Kobe");
System.out.println(p1.getName());
System.out.println(p2.getName());
////********一般對象創建,一個對象對應一個實例************///
System.out.println("懶漢式單例創建");
LazyPerson hp1 = LazyPerson.getInstance();
LazyPerson hp2 = LazyPerson.getInstance();
hp1.setName("T-Mac");
hp2.setName("Kobe");
System.out.println(hp1.getName());
System.out.println(hp2.getName());
////***********懶漢式單例創建*****************************////
System.out.println("餓漢式單例創建");
HungryPerson lp1 = HungryPerson.getInstance();
HungryPerson lp2 = HungryPerson.getInstance();
lp1.setName("T-Mac");
lp2.setName("Kobe");
System.out.println(lp1.getName());
System.out.println(lp2.getName());
////***********餓漢式單例創建*****************************////
System.out.println("雙重檢查單例創建");
DoubleCheckPerson dcp1 = DoubleCheckPerson.getInstance();
DoubleCheckPerson dcp2 = DoubleCheckPerson.getInstance();
dcp1.setName("T-Mac");
dcp2.setName("Kobe");
System.out.println(dcp1.getName());
System.out.println(dcp2.getName());
////***********雙重檢查單例創建*****************************////
}
}