java中單例模式是一種常見的設計模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。
單例模式有一下特點:
1、單例類只能有一個實例。
2、單例類必須自己自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。在計算機系統中,線程池、緩存、日誌對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每臺計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。總之,選擇單例模式就是爲了避免不一致狀態,避免政出多頭。
//(1)單例模式:餓漢式--------------
public class Singleton {
//私有,靜態的類自身實例
private static Singleton instance = new Singleton();
//私有無參構造
private Singleton(){}
//公開,靜態工場方法
public static Singleton getInstance(){
return instance;
}
}
//使用時 Singleton obj = Singleton.getInstance;
//(2)單例模式:懶漢式------------------
public class LazySingleton {
//初始爲null,暫不實例化
private static LazySingleton instance= null;
//私有無參構造
private LazySingleton(){}
//公開,靜態工場方法,需要使用時才創建該對象
public static LazySingleton getInstance(){
if(instance==null){
instance = new LazySingleton();
}
return instance;
}
}
//使用時跟上面例子一樣 LazySingleton obj = LazySingleton.getInstance;
package day0825singleton;
public class TestStream {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//該類只能有一個實例
private TestStream(){}
//該類必須自行創建
//有2種方式
//private static final TestStream ts = new TestStream();//方式1
//方式2:
private static TestStream ts = null;
//該類必須自動向整個系統提供這個實例對象
public static TestStream getTest(){
if(ts==null){
ts = new TestStream();
}
return ts;
}
public void getInfo(){
System.out.println("name:"+name);
}
}
package day0825singleton;
public class TestMain {
public static void main(String[] args) {
TestStream ts = TestStream.getTest();
ts.setName("張三");
System.out.println(ts.getName());
ts.getInfo();
TestStream ts1 = TestStream.getTest();
ts1.setName("李四");
System.out.println(ts1.getName());
ts1.getInfo();
System.out.println(ts==ts1);//結果true,
//由結果可以得知單例模式爲一個面向對象的應用程序提供了對象惟一的訪問點,不管它實現何種功能,整個應用程序都會同享一個實例對象。
}
}
登記式單例:
package day0825singleton;
import java.util.HashMap;
import java.util.Map;
//登記式單例
//類似Spring裏面的方法,將類名註冊,下次從裏面直接獲取。
public class Singleton3{
private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保護的默認構造子
private Singleton3(){}
//靜態工廠方法,返還此類惟一的實例
public static Singleton3 getInstance(String name){
if(name == null){
name = Singleton3.class.getName();
System.out.println("name爲空則設定name爲:"+name);
}
if(map.get(name)==null){
try {
map.put(name, (Singleton3)Class.forName(name).newInstance());
//forName:返回與帶有給定字符串名的類或接口相關聯的 Class 對象。
//.newInstance()創建類的無參對象
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一個示意性的商業方法
public String about(){
return "Hi, i am a Singleton";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
/*運行結果:
name爲空則設定name爲:day0825singleton.Singleton3
Hi, i am a Singleton
*/