單例模式(Singleton)

通常實現git

  • 建立執行方法
public class WithoutSingleton {
    public static void withoutSingletonInfo(WithoutSingleton withoutSingleton){
        System.out.println("WithoutSingleton.hashCode = " + withoutSingleton.hashCode());
    }
}
  • 測試類
public static void main(String[] args) {
        WithoutSingleton withoutSingleton = new WithoutSingleton();
        WithoutSingleton.withoutSingletonInfo(withoutSingleton);
        WithoutSingleton withoutSingleton2 = new WithoutSingleton();
        WithoutSingleton.withoutSingletonInfo(withoutSingleton2);
        WithoutSingleton withoutSingleton3 = new WithoutSingleton();
        WithoutSingleton.withoutSingletonInfo(withoutSingleton3);
    }
  • 輸出
WithoutSingleton.hashCode = 2083479002
WithoutSingleton.hashCode = 163238632
WithoutSingleton.hashCode = 1215070805
  • 問題
    每次生成的類的實例對象都是不一樣的,可是在一些特定的場合,須要每次返回的實例對象都是同一個,如:sping中建立bean。

懶漢式單例模式github

  • 單例類
public class LazySingleton {
    private static LazySingleton lazySingleton = null;
    private LazySingleton(){
    }
    public static LazySingleton getInstance(){
        if(lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
    public static void singletonInfo(){
        System.out.println("lazySingleton.hashCode = " + lazySingleton.hashCode());
    }
}
測試類:
public static void main(String[] args) {
        LazySingleton lazySingleton = LazySingleton.getInstance();
        lazySingleton.singletonInfo();
        LazySingleton lazySingleton2 = LazySingleton.getInstance();
        lazySingleton2.singletonInfo();
        LazySingleton lazySingleton3 = LazySingleton.getInstance();
        lazySingleton3.singletonInfo();
    }
輸出:
lazySingleton.hashCode = 1110594262
lazySingleton.hashCode = 1110594262
lazySingleton.hashCode = 1110594262
  • 實現方式

    構造方法私有化。安全

  • 存在問題

    線程不安全,若是多個線程同時訪問,仍會產生多個實例對象。性能

  • 解決方法
    1.在getInstance()方法上同步synchronized(同步對性能有影響)
    2.雙重檢查鎖定
    3.靜態內部類

餓漢式單例模式測試

  • 代碼實現
public class HungrySingleton {
    private static HungrySingleton hungrySingleton = new HungrySingleton();
    private HungrySingleton(){
    }
    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
    public static void singletonInfo(){
        System.out.println("hungrySingleton.hashCode = " + hungrySingleton.hashCode());
    }
}
  • 輸出
hungrySingleton.hashCode = 1977385357
hungrySingleton.hashCode = 1977385357
hungrySingleton.hashCode = 1977385357
  • 說明
    靜態成員變量在類加載的時候就會建立實例對象,解決了線程不安全問題
  • 缺點
    類加載時就建立實例對象,會佔用系統內存,若是存在大量單例類(通常不會出現),或者建立的類並無使用,會形成內存浪費。

源碼線程

https://github.com/Seasons20/DisignPattern.git

ENDcode

相關文章
相關標籤/搜索