1. 程式人生 > >單例模式詳解

單例模式詳解

餓漢式 登記式 懶漢式 單例

單例設計模式

Singleton是一種創建型模式,指某個類采用Singleton模式,則在這個類被創建後,只可能產生一個實例供外部訪問,並且提供一個全局的訪問點。

核心知識點如下:

(1) 將采用單例設計模式的類的構造方法私有化(采用private修飾)。

(2) 在其內部產生該類的實例化對象,並將其封裝成private static類型。

(3) 定義一個靜態方法返回該類的實例。

餓漢式
優點是:寫起來比較簡單,而且不存在多線程同步問題,避免了synchronized所造成的性能問題;
缺點是:當類Singleton被加載的時候,會初始化static的instance,靜態變量被創建並分配內存空間,從這以後,這個static的instance對象便一直占著這段內存(即便你還沒有用到這個實例),當類被卸載時,靜態變量被摧毀,並釋放所占有的內存,因此在某些特定條件下會耗費內存。

/** 
 * 單例模式的實現:餓漢式,線程安全 但效率比較低 
 */  public class Singleton {  

    // 定義一個私有的構造方法    
    private Singleton() {  
    }  

    // 將自身的實例對象設置為一個屬性,並加上Static和final修飾符    
    private static final Singleton instance = new Singleton();  

    // 靜態方法返回該類的實例    
    public static Singleton getInstancei() {  
        return instance;  
    }  
  
}

懶漢式

優點是:寫起來比較簡單,當類Singleton被加載的時候,靜態變量static的instance未被創建並分配內存空間,當getInstance方法第一次被調用時,初始化instance變量,並分配內存,因此在某些特定條件下會節約了內存;
缺點是:並發環境下很可能出現多個Singleton實例,非線程安全

/**  
 * 單例模式的實現:懶漢式非線程安全   
 *   
 */  public class Singleton {

    // 定義私有構造方法(防止通過 new Singleton()去實例化)    
    private Singleton() {   
    }   

    // 定義一個Singleton類型的變量(不初始化,註意這裏沒有使用final關鍵字)  
    private static Singleton instance;   

    // 定義一個靜態的方法(調用時再初始化SingletonTest,但是多線程訪問時,可能造成重復初始化問題)   
    public static Singleton getInstance() {   
      if (instance == null)   
       instance = new Singleton();   
      return instance;   
    }   
}

懶漢式優化一
優點是:使用synchronized關鍵字避免多線程訪問時,出現多個Singleton實例。
缺點是:同步方法頻繁調用時,效率略低。

/**  
 * 單例模式的實現:懶漢式,線程安全簡單實現   
 *   
 */  public class Singleton {

    // 定義私有構造方法(防止通過 new Singleton()去實例化)
    private Singleton() {   
    }   

    // 定義一個Singleton類型的變量(不初始化,註意這裏沒有使用final關鍵字)
    private static Singleton instance;   

    // 定義一個靜態的方法(調用時再初始化Singleton,使用synchronized 避免多線程訪問時,可能造成重的復初始化問題)
    public static synchronized  Singleton getInstance() {   
        if (instance == null)   
          instance = new Singleton();   
        return instance;   
    }   
}

懶漢式優化二

單例模式的最佳實現。內存占用地,效率高,線程安全,多線程操作原子性。

/**  
 * 單例模式懶漢式最優方案
 * 線程安全並且效率高  
 *   */  
 public class Singleton { 

    // 定義一個私有構造方法   
    private Singleton() { 
     
    }   
    //定義一個靜態私有變量(不初始化,不使用final關鍵字,使用volatile保證了多線程訪問時
    //instance變量的可見性,避免了instance初始化時其他變量屬性還沒賦值完時,被另外線程調用)    
    private static volatile Singleton instance;  

    //定義一個共有的靜態方法,返回該類型實例    
    public static Singleton getIstance() { 
     //對象實例化時與否判斷(instance等於null時,不進入同步代碼塊,直接返回對象,提高運行效率)        
     if (instance == null) {
       //同步代碼塊(對象未初始化時,使用同步代碼塊,保證多線程訪問時對象在第一次創建後,不再重復被創建)            
        synchronized (Singleton.class) {
      //未初始化,則初始instance變量                
       if (instance == null) {
       instance = new Singleton();   
       }   
       }   
      }   
     return instance;   
    }   
}

登記式

內部類只有在外部類被調用才加載,產生Singleton實例,又不用加鎖,此模式有上述倆模式的優點,屏蔽了他們的缺點,是最好的單例模式

public class Singleton{  
 // 定義一個私有構造方法     
 private Singleton(){}  
 
 public static Singleton getInstance(){ 
    return Holder.singleton;
 }   
 //內部類
 private static class Holder{
    private static final Singleton singleton= new Singleton();
 }
}


參考:http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html

本文出自 “ciyo技術分享” 博客,請務必保留此出處http://ciyorecord.blog.51cto.com/6010867/1939382

單例模式詳解