java單例模式之餓漢式、懶漢式
一、單例設計模式是指java中某一個類只有一個例項,並且自行例項化對外提供服務。
1、如何保證物件的唯一性?
①、不允許其它程式使用new方式建立新的例項。
②、在該類中建立一個唯一的物件例項。
③、提供方法,共外界呼叫該例項。
2、步驟:
①、通過new方式私有化該類的一個物件例項。
②、私有化構造方法,其他程式無法建立例項。
③、提供公有的get方法,共外界呼叫該例項。
二、單例設計模式的幾種設計方式
1、餓漢式
> class TestSingle{
private static TestSingle single=new TestSingle();
private TestSingle() {}
public static TestSingle getInstance() {
return single;
}
}
2、懶漢式(延遲載入模式)
> class TestSingle{
private static TestSingle single=null;
private TestSingle() {}
//這裡必須是靜態的,因為建構函式私有的,無法建立例項物件,只能通過類名呼叫。
public static TestSingle getInstance() {
if(single==null) {
single=new TestSingle();
}
return single;
}
}
三、多執行緒下的單例
1、餓漢式在類建立好的時候,就已經初始化好了一個物件例項,且提供方法對外訪問,以後不會再改變,天生就是安全的。
2、懶漢式存線上程安全問題,有可能建立多個例項,違反單例唯一的情況,因此要解決執行緒安全問題。
①、雙重檢查鎖定
> class Single1 implements Runnable{
private static Single1 single1=null;
public static Single1 getIntance() {
//第一個if判斷句解決了執行緒效率問題
if(single1==null) {
synchronized(Single1.class) {
//第二個if語句解決了執行緒不安全問題
if(single1==null)
single1=new Single1();
}
}
return single1;
}
public void run() {
System.out.println(getIntance());
}
}
②、同步函式(在getIntance方法上加上同步)
> public synchronized static Single1 getIntance() {
if(single1==null)
single1=new Single1();
return single1;
}
③、靜態內部類
>class TestSingle{
private static class Single {
private static TestSingle single=new TestSingle();
}
private TestSingle(){}
public static TestSingle getIntance(){
return Single.single;
}
}
四、餓漢式與懶漢式的區別
1、餓漢式是執行緒安全的,懶漢式執行緒不安全。
2、餓漢式不管系統用不用到該例項,都會在程式載入時先建立一個例項,佔用記憶體資源,但在以後呼叫過程中會比較快。
懶漢式在需要用到時才會建立例項,第一次呼叫會比較慢,之後就和懶漢式想同了。
3、程式設計中常使用餓漢式。
五、在懶漢式的執行緒安全解決上
①、雙重檢查鎖定使用了兩次if判斷語句,很好的解決了執行緒安全問題,同時避免了同步帶來的效率問題。
②、使用同步函式,對效率影響比較大,因為每次使用都要同步,而我們大部分情況是不需要同步的。
③、使用內部類是執行緒安全的,同時沒有效能損耗。