單列模式之餓漢式,懶漢式

2021-08-17 03:38:58 字數 3877 閱讀 6294

懶漢式的特點是延遲載入,比如配置檔案,採用懶漢式的方法,顧名思義,懶漢麼,很懶的,配置檔案的例項直到用到的

時候才會載入。。。。。。

餓漢式的特點是一開始就載入了,如果說懶漢式是

「時間換空間」,那麼餓漢式就是「空間換時間」,因為一開始就建立了例項,所以每次用到的之後直接返回就好了

1.惡漢式

public class singleton

private static singleton newinsance()

}

從上面的**中可以看見,類的構造方法是用

private(私有化)定義的,那麼其他類不能例項化此類,並且提供乙個靜態的例項並用靜態方法返回給呼叫者,餓漢模式只不過是最簡單的一種實現方式,餓漢模式在類載入的時候就對例項進行建立,例項在整個程式週期都存在,好處是只在類載入的時候建立一次例項,不會存在多個執行緒建立多個例項的情況,避免了多執行緒同步的問題,它的缺點也很明顯,即使這個類沒有用到也會被建立,而且在類載入之後就被建立,記憶體就會被浪費。所以餓漢模式的使用場景是在這個類在初始化的時候就會被用到,並且單例模式占用記憶體小,如果在某個特定情景下才會被用到那就不合適了。

2.懶漢式

public class singleton

public static singleton newinstance()

return singleton;

}

}

餓漢式和懶漢式的基本實現效果是一樣的,只不過懶漢式比餓漢式多了一層判斷,如果這個單例模式被呼叫,並且單利模式沒有被

new,就會進入if()中,如果已經存在那麼就返回給呼叫者,這就解決了餓漢式的問題,但是懶漢式他的執行緒是不安全的,當多執行緒同時呼叫他的newinteger()方法,那麼他就有可能建立出多個來(想不明白,怎麼學的執行緒),所以就需要給它加鎖來解決這個問題。

3.懶漢式(微調版)

public class singleton

public static synchronized singleton newinstance()

return  singleton;

}

}

它比上面的懶漢式多加了個

synchronized 的修飾符,不明白??多執行緒。

微調版的懶漢式看起來及解決了執行緒的併發問題,有實現了延遲載入,但是它存在著效能問題,因為

synchronized修飾的同步方法比一般方法要慢的多,而且多次呼叫newinstance()方法也就多次呼叫了synchronized修飾符,累積的效能損耗就比較大,所以就有了二次公升級版本

4.懶漢式(二次公升級)

public class singleton

public static singleton newinstance()

}

}

return singleton;

}

}

可以看上面在同步**塊外多了一層物件為空的判斷,由於單例物件只需要常見一次,如果後面再次呼叫此方法只需要直接返回單例物件,因此,大部分情況下,呼叫上面的方法都不會執行到同步**塊,從而提高了程式效能,不過還有多一點,執行緒問題,假若當

5.懶漢式(三次公升級)

現在看來雙重校驗鎖即實現了延遲載入,又解決了執行緒的併發問題,同時還解決了執行效率問題,但是還有個指令重排優化,即指在不改變原語義的情況下,通過調整指令的執行順序讓程式執行的更快,

jvm並沒有規定編譯器優化相關的內容,也就是說jvm可以自由的進行指令重排序的優化。

這個問題的關鍵就在於由於指令重排優化的存在,導致初始化

singleton和將物件的位址賦給instance欄位的順序是不正確的。在某個執行緒建立的單例物件時,在構造方法被呼叫之前,就為給物件分配了記憶體空間並將物件的字段設定為預設值。此時就可以將分配的記憶體位址賦值給instance欄位了,然而該物件可能還沒有初始化,若緊接著另外乙個執行緒來呼叫getinstance,取到的基石狀態不正確的物件,程式就會出錯。

好在

jdk1.5之後版本增加了volatile關鍵字。volatile的乙個語義是禁止指令重排序優化,也就能保證instance變數被賦值的時候物件已經初始化了,

public class singleton

public static singleton newinstance()

}

}

return singleton;

}

}

6.靜態內部類

這種方法同樣利用了類載入機制來保證只建立了個

instance例項,他和餓漢式一樣,也是利用了類載入機制,一次不存在多執行緒併發問題,不一樣的是,他是內部類裡面去建立的物件例項。這樣的話。只要應用中不適用內部類,jvm就不會載入這個單例類,也就不會常見單例物件,從而實現懶漢式的延遲載入,也就是同時保證了延遲載入和執行緒安全。

public class singleton

public singleton()

public static singleton newinstance()

}

7.列舉

public enum  singleton ;

}

前面實現單例的方式都有那些共同的缺點,

(1.需要額外的工作來實現序列化,否則每次反序列化乙個序列化的物件時都會建立乙個新的例項。

(2.可以使用反射強行呼叫私有構造器(如果要避免這種情況,可以修改構造器,讓他在建立第二個例項的時候拋異常)

而列舉類很好的解決了這兩個問題,使用列舉除了執行緒安全和防止反射呼叫構造器之外,還提供了自動序列化機制,防止反序列化的時候建立新的物件。

單列模式之餓漢式和懶漢式

單列模式的特點 從系統的啟動到終止,這個過程只會產生乙個物件 懶漢式 懶漢式,只有在使用的時候才會new物件 package com.tian.day03 object singletonops1 start class singleton1 private object singleton1 si...

轉 單列模式懶漢式,餓漢式

1 單例模式singleton a.只能有乙個例項 b.例項必須由單例類自己建立,自己new c.所有物件共享這乙個例項 2 餓漢式 public class eagersingleton 靜態工廠方法 public static eagersingleton getinstance 3 懶漢式 p...

單列模式,懶漢 ,餓漢

設計模式之 單例 1 什麼是單例 就字面理解即可 乙個專案只有乙個例項物件 模式 最常見的兩種 懶漢和餓漢 區別1就在於例項化物件的時機不同 區別2 關於執行緒安全問題 public class singinstancedemo t1,t2,t3 public synchronized singin...