程序設計優化——(1)單例模式(懶漢、餓漢及單例模式優化)

  簡介:單例模式是設計模式中使用比較廣泛的設計模式,也是很是簡單的一種設計模式。單例模式是指確保系統中只有一個實例。最多見的單例模式分爲懶漢模式和餓漢模式。java

1. 單例模式的好處:設計模式

  1)對於頻繁使用的對象,能夠省去建立對象的開銷;多線程

  2)因爲new操做的次數減小,於是對系統內存的使用頻率也會下降,從而減小系統GC的時間。性能

2. 單例模式造成的條件優化

  1)必需要有一個私有構造器spa

  2)單例對象變量須要是私有的靜態static線程

3. 餓漢模式( 這個漢子太餓了,一上來就直接new 對象實例)設計

  實現代碼:code

  SingletonDemoHungry.java對象

/**
 * <p>Description: 單例模式
 *     餓漢模式
 * </p>
 * @author Huang Xiaocong
 * @data 2019年10月27日
 */
public class SingletonDemoHungry {
    
    private SingletonDemoHungry() {    //私有構造器
        System.out.println("建立單例模式");    //實際開發中,建立單例模式的時候可能比較慢
    }
    private static SingletonDemoHungry instance = new SingletonDemoHungry();
    
    public static SingletonDemoHungry getInstance() {
        return instance;
    }    
}

 

  優勢:這種單例模式的實現方式簡單可靠。

  缺點:沒法對對象實例(instance)作延遲加載。假如在單例的建立過程很慢,而因爲instance成員變量是static定義的,因此在加載單例類的過程當中也會一塊兒加載。若單例類中還存在其餘static方法或者變量,也會一塊兒加載。而且在其餘地方使用該單例類時也會被加載屢次。

  如SingletonDemoHungry.java單例類中還存在其餘靜態方法:

  public static void printInfo() {
        System.out.println("printInfo in SingletonDemoHungry!!");
    }

  在其餘地方調用SingletonDemoHungry.printInfo(); 時, 程序將打印以下信息。程序並無使用單例類,但instance實例仍是被建立出來了。

建立單例模式
printInfo in SingletonDemoHungry!!

  爲了解決上述這個問題,可使用餓漢模式。

4.懶漢模式(這個漢子太懶了,直到要使用的時候才new 對象)

  SingletonDemoLazy.java

/**
 * <p>Description: 懶漢模式</p>
 * @author Huang Xiaocong
 * @data 2019年10月27日
 */
public class SingletonDemoLazy {

    private static SingletonDemoLazy instance = null;
    private SingletonDemoLazy() {
        System.out.println("建立單例模式");    //實際開發中,建立單例模式的時候可能比較慢
    }
    public static synchronized SingletonDemoLazy getInstance() {
        if(instance == null) {
            instance = new SingletonDemoLazy();
        }
        return instance;
    }
}

 該懶漢模式與餓漢模式相比,引入了延遲加載機制。但其中的getInstance()方法必須是同步的,不然在多線程環境下,當線程1在新建單例時,建立完正打算賦值時,線程2可能判斷instance爲null,同時進行建立對象,而致使多個實例被建立。雖然實現了延遲加載的功能,可是同時又引入了新的問題,使用synchronized關鍵字,在多線程環境中,它的時耗遠遠大於餓漢模式。

  爲了使用延遲加載反而下降了系統性能,得不償失,可對其進行改進優化

/**
 * <p>Description: 改進的懶漢模式</p>
 * @author Huang Xiaocong
 * @data 2019年10月27日
 */
public class SingletonDemoNewLazy {

    private SingletonDemoNewLazy() {
        System.out.println("SingletonDemoNewLazy.SingletonDemoNewLazy()");
    }
    //內部類SingletonHolder
    private static class SingletonHolder {
        private static SingletonDemoNewLazy instance = new SingletonDemoNewLazy();
    }
    
    public static SingletonDemoNewLazy getInstance() {
        return SingletonHolder.instance;
    }
}

 

改進後的單例模式使用內部類維護單例類的實例,當SingletonDemoNewLazy被加載時,其內部類並不會被初始化。而只有當調用getInstance()方法時纔會調用加載SingletonHolder。即最後的SingletonDemoNewLazy.java既實現了延遲加載,也沒必要使用同步機制。

相關文章
相關標籤/搜索