Java設計模式之單例模式(Singleton)

總李寫程式碼發表於2016-05-30

前言:

     在總結okHttp的時候,為了管理網路請求使用到了單例模式,晚上實在沒啥狀態了,靜下心來學習總結一下使用頻率最高的設計模式單例模式。

 單例模式:

       單例模式確保某個類只有一個例項,而且自行例項化並向整個系統提供這個例項。

單例特點:

  • 單例類只能有一個例項。
  • 單例類必須自己建立自己的唯一例項。
  • 單例類必須給所有其他物件提供這一例項。

單例分類:

     1).懶漢單例

    (1)非執行緒安全實現

public class Singleton {     
 
    private Singleton(){     
    }     

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

  (2)執行緒安全實現方式一  方法加同步 這種實現方式效率不高

public class Singleton {        

    private Singleton(){     
    }     

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

 (3.)執行緒安全實現方式二 雙重檢查鎖定

public class Singleton{  
  private static Singleton single;    //宣告靜態的單例物件的變數  
  private Singleton(){}    //私有構造方法   

  public static Singleton getSingle(){    //外部通過此方法可以獲取物件    
    if(single == null){     
        synchronized (Singleton.class) {   //保證了同一時間只能只能有一個物件訪問此同步塊        
            if(single == null){      
                single = new Singleton();          
            }     
        }  
    }    
    return single;   //返回建立好的物件   
  }  
}  

2.)餓漢式單例類

      餓漢式在類建立的同時就已經建立好一個靜態的物件供系統使用,以後不再改變,所以天生是執行緒安全的。

public class Singleton  {  

    private Singleton(){  
    }  

    private final static Singleton instance = new Singleton();  

    private static Singleton getInstance(){  
        return instance;  
    }  
} 

 

3.)內部類式單例類

內部類式中,實現了延遲載入,只有我們呼叫了getInstance(),才會建立唯一的例項到記憶體中.並且也解決了懶漢式中多執行緒的問題.解決的方式是利用了Classloader的特性,既實現了執行緒安全,又避免了同步帶來的效能影響。

public class Singleton{        
     private Singleton(){     
      }     

    private static class SingletonHolder(){     
        private static Singleton instance = new Singleton();     
    }     

    private static Singleton getInstance(){     
        return SingletonHolder.instance;     
    }     
} 

 

4.)列舉類單例

《Effective Java》作者推薦使用的方法,優點:不僅能避免多執行緒同步問題,而且還能防止反序列化重新建立新的物件

public enum Singleton {
    /**
     * 定義一個列舉的元素,它就代表了Singleton的一個例項。
     */
    
    uniqueInstance;
    
    /**
     * 單例可以有自己的操作
     */
    public void doSomeThing(){
        //功能處理
    }
}

5.)懶漢和餓漢區別

(1)初始化角度

     餓漢就是類一旦載入,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,而懶漢比較懶,只有當呼叫getInstance的時候,才回去初始化這個單例

(2)執行緒安全形度

     餓漢式天生就是執行緒安全的,可以直接用於多執行緒而不會出現問題,懶漢式本身是非執行緒安全的,需要自己實現執行緒安全的方法。

 

相關文章