單例模式咱們在開發中常常用到,可是咱們可能熟知一種單例模式,可是單例模式也有好多種,如今就對幾種單例模式作個比較,明白其中的優缺點:設計模式
public class Singleton{ private static Singleton single=new Singleton(); private Singleton(){ System.out.println("生成一個Singleton實例"); } public static Singleton getInstance(){ return single; } }
2.測試代碼安全
public class SingletonTest{ public static void main(String[] args){ System.out.println("Start..."); Singleton single1=Singleton.getInstance(); Singleton single2=Singleton.getInstance(); if(single1==single2){ System.out.println("obj1 和 obj2 是相同的實例。"); }else{ System.out.println("obj1 和 obj2 是不一樣的實例。"); } System.out.println("End..."); } }
3.測試結果網絡
Start...
生成一個Singleton實例
obj1 和 obj2 是相同的實例。
End...多線程
public class Singleton{ private static Singleton single=null; private Singleton(){ System.out.println("生成一個Singleton實例"); } public static Singleton getInstance(){ if(single==null){ single=new Singleton(); } return single; } }
5.不是嚴格單例模式測試代碼ide
public class SingletonThread implements Runnable { private Set<Singleton> set=new HashSet<Singleton>(); @Override public void run() { Singleton single=Singleton.getInstance(); set.add(single); System.out.println("Set的大小爲:"+set.size()+","+set); } }
測試類Main方法函數
public class SingleTest { public static void main(String[] args) { SingletonThread t=new SingletonThread(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); } }
6.測試結果:會看到會有多個「生成一個Singleton實例」,說明調用了5次 new Singleton()方法。測試
7.若是使用第一種方法的話:只會有一個「生成一個Singleton實例 」,說明只調用了一次 new Singleton() 方法。線程
8.爲了解決第二種多線程安全問題,採用對函數進行同步的方式,可是也比較浪費資源,由於每次都要進行同步檢查,而實際真正須要檢查的只是第一次。(單例模式的第三個版本)設計
public class Singleton{ private static Singleton single=null; private Singleton(){ System.out.println("生成一個Singleton實例"); } public static synchronized Singleton getInstance(){ if(single==null){ single=new Singleton(); } return single; } }
運行結果:3d
9.(單例模式的第四個版本)既解決了「懶漢式」多線程的安全問題,又解決了浪費資源的現象。
public class Singleton{ private static Singleton single; private Singleton(){ System.out.println("生成一個Singleton實例"); } public static Singleton getInstance(){ if(single==null){ synchronized(Singleton.class) { if(single==null) { single=new Singleton(); } } } return single; } }
運行結果:
10.單例模式優缺點總結:
優勢:客戶端使用單例模式的實例的時候,只須要調用一個單一的方法就能夠獲得一個惟一的實例,有利於節省資源。缺點:首先單例模式很難實現實例化,這就致使採用單例模式的類很難被持久化,固然也很難經過網絡進行傳輸;其次,因爲單例採用靜態方法,沒法再繼承結構中使用。