單例模式總結


單例模式的含義

單例模式的意思就是只有一個實例。單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例

一般只有一個私有的構造方法,它可以通過調用公共的靜態方法來獲得這個實例

單例模式的好處

主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。

使用Singleton的好處還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收

單例模式特點

1、單例類只能有一個實例。

2、單例類必須自己創建自己的唯一實例。

3、單例類必須給所有其他對象提供這一實例。

 

單例模式的選型:

 在實現層面上,目前的幾種主要的單例模式往往有以下幾項性能指標作為選型參考:

  -- 是否實現延遲加載

  -- 是否線程安全

  -- 並發訪問性能

  -- 是否可以防止反射與反序列化穿透

一個線程訪問一個對象中的synchronized(this)同步代碼塊時,其他試圖訪問該對象的線程將被阻塞。

1.懶漢式單例

在類加載的時候不創建單例實例。只有在第一次請求實例的時候的時候創建,並且只在第一次創建后,以后不再創建該類的實例。
懶漢式如果在創建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的

//單例模式-懶漢式單例
public class LazySingleton {
     //私有靜態對象,加載時候不做初始化
     private static LazySingleton m_intance=null;
     // 私有構造方法,避免外部創建實例
     private LazySingleton(){}
     /**
      * 靜態工廠方法,返回此類的唯一實例. 
      * 當發現實例沒有初始化的時候,才初始化.
      */
     synchronized public static LazySingleton getInstance(){
         if(m_intance==null){
             m_intance=new LazySingleton();
         }
         return m_intance;
     }
}

 

2. 餓漢式單例  

 在類加載的時候就創建實例,,在類創建的同時就已經創建好一個靜態的對象供系統使用

/*
* 單例模式-餓漢式單例
*/
public class EagerSingleton {
     /*
      * 私有的(private)唯一(static final)實例成員,在類加載的時候就創建好了單例對象
      */
     private static final EagerSingleton m_instance = new EagerSingleton();

     /**
      * 私有構造方法,避免外部創建實例
      */
     private EagerSingleton() {
     }

     /**
      * 靜態工廠方法,返回此類的唯一實例.
      * @return EagerSingleton
      */
     public static EagerSingleton getInstance() {
         return m_instance;
     }
}

3. 登記式單例

這個單例實際上維護的是一組單例類的實例,將這些實例存放在一個HashTable(登記薄)中,對於已經登記過的實例,則從工廠直接返回,對於沒有登記的,則先登記,而后返回。 

//用來存儲單例(StringManager)的變量的hash類
private static HashTable managers = new HashTable();
//下面用關鍵字synchronized避免多線程時出錯。
public synchronized static StringManager getManager(String packageName){
    StringManager mgr = (StringManager)managers.get(packageName);
    if(mgr == null){
        mgr = new StringManager(packageName);
        managers.put(packageName,mgr);
   }
return mgr;
}

4.雙重鎖定單例(改進懶漢式)

考慮這樣一種情況,就是有兩個線程同時到達,即同時調用 getInstance() 方法。兩個線程都會創建一個實例,這就違背了單例模式的初衷。因此加雙重鎖定

public class Singleton {  
    private static volatile Singleton instance;  
  
    private Singleton() {  
    }  
  
    public static Singleton getInstance() {  
        if (instance == null) {  
            synchronized (Singleton.class) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    }  
}  

  

啊啊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM