定義:java
單例模式是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例的特殊類。經過單例模式能夠保證系統中一個類只有一個實例。即一個類只有一個對象實例。編程
特色:設計模式
一、單例類只能有有一個實例。服務器
二、單例類必須本身建立本身的惟一實例併發
三、單例類必須給全部其餘對象提供這一實例函數
單例模式的要點:高併發
一、私有的構造方法性能
二、指向本身實例的私有靜態引用spa
三、以本身實例爲返回值的靜態的公有的方法線程
單例模式根據實例化對象時機的不一樣分爲兩種:
一種是餓漢式單例,一種是懶漢式單例。
餓漢式單例在單例類被加載時候,就實例化一個對象交給本身的引用;而懶漢式在調用取得實例方法的時候纔會實例化對象。
代碼以下:
餓漢式單例
public class Singleton { private static Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return singleton; } }
懶漢式單例
public class Singleton { private static Singleton singleton; private Singleton(){} public static synchronized Singleton getInstance(){ if(singleton==null){ singleton = new Singleton(); } return singleton; } }
單例模式還有一種比較常見的形式:雙重鎖的形式
public class Singleton{ private static volatile Singleton instance=null; private Singleton(){ //do something } public static Singleton getInstance(){ if(instance==null){ synchronized(SingletonClass.class){ if(instance==null){ instance=new Singleton(); } } } return instance; } }
這個模式將同步內容下方到if內部,提升了執行的效率,沒必要每次獲取對象時都進行同步,只有第一次才同步,建立了之後就不必了。
這種模式中雙重判斷加同步的方式,比第一個例子中的效率大大提高,由於若是單層if判斷,在服務器容許的狀況下,假設有一百個線程,耗費的時間爲100*(同步判斷時間+if判斷時間),而若是雙重if判斷,100的線程能夠同時if判斷,理論消耗的時間只有一個if判斷的時間。
因此若是面對高併發的狀況,並且採用的是懶漢模式,最好的選擇就是雙重判斷加同步的方式。
單例模式的優勢:
一、在內存中只有一個對象,節省內存空間
二、避免頻繁的建立銷燬對象,能夠提升性能
三、避免對共享資源的多重佔用
四、能夠全局訪問
單例模式的缺點:
一、擴展困難,因爲getInstance靜態函數沒有辦法生成子類的實例。若是要拓展,只有重寫那個類。
二、隱式使用引發類結構不清晰
三、致使程序內存泄露的問題
適用場景:
因爲單例模式的以上優勢,因此是編程中用的比較多的一種設計模式。如下爲使用單例模式的場景:
1,須要頻繁實例化而後銷燬的對象。
2,建立對象時耗時過多或者耗資源過多,但又常常用到的對象。
3,資源共享的狀況下,避免因爲資源操做時致使的性能或損耗等
4,控制資源的狀況下,方便資源之間的互相通訊。