我理解的單例設計模式

單例模式咱們在開發中常常用到,可是咱們可能熟知一種單例模式,可是單例模式也有好多種,如今就對幾種單例模式作個比較,明白其中的優缺點:設計模式

  1. 單例代碼:「餓漢式」,也就是當類加載進來的時候就建立實例,可是這種方式比較消耗資源。(單例模式的第一個版本)
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...多線程

  1. 不是嚴格的Singleton模式的例子:「懶漢式」:單線程下能夠,多線程下存在線程安全問題。(單例模式的第二個版本), 這段代碼若是是在單線程中是沒有什麼問題的,可是由於沒有鎖的機制,在多線程中就會有問題,當同一時間有兩個或者兩個以上線程進入getInstance()方法時,由於剛開始single都是null , 幾個線程都同時知足if(single==null) 這個條件,就會同時new Singleton() 這個對象
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.單例模式優缺點總結:

優勢:客戶端使用單例模式的實例的時候,只須要調用一個單一的方法就能夠獲得一個惟一的實例,有利於節省資源。缺點:首先單例模式很難實現實例化,這就致使採用單例模式的類很難被持久化,固然也很難經過網絡進行傳輸;其次,因爲單例採用靜態方法,沒法再繼承結構中使用。

相關文章
相關標籤/搜索