天天看點

java程式性能優化_設計優化_單例模式

單例模式應該大家都學習過。單一個對象需要被頻繁使用,使用單例模式,可以節省建立對象消耗的時間,也能節省記憶體。下面介紹幾種單例的建立方法,和性能對比。

(1)普通方式,私有化構造函數,使用靜态變量進行初始化,在類被加載的時候初始化

class Singleton
{
    private static Singleton instance = new Singleton();
    private Singleton()
    {
        System.out.println("Singleton is create");
    }

    public  static Singleton getInstance()
    {
        return instance;
    }

    public static void createString()
    {
        System.out.println("createString in Singleton");
    }

}
           

(2)延遲加載的單例模式(懶漢模式),當第一次調用的時候,初始化執行個體,需使用同步機制,保證線程安全

class LazySingleton
{
    private LazySingleton()
    {
        System.out.println("LazySingleton is create");
    }


    private static LazySingleton instance = null;

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

    }

}
           

(3)使用内部靜态内部類的單例模式,使用内部類,讓jvm虛拟機,直接保證線程安全,該方法優于(2)

class StaticSingleton
{
    private StaticSingleton()
    {
        System.out.println("StaticSingleton is create");
    }

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

    public static StaticSingleton getInstance()
    {
        return SingletonHolder.instance;
    }

    public static void createString()
    {
        System.out.println("createString in Singleton");
    }

}
           

(4)對比(1)(2)(3)三種模式的單例模式性能

import java.io.*;

public class SingletonTest {

    public static void main(String[] args) {
       StaticSingleton.createString();

      long time = System.currentTimeMillis();
        System.out.println("time is "+time);
        int max = 1000000;
        for(int i = 0; i < max;i++)
        {
            Singleton.getInstance();
        }
        System.out.println("spend :"+(System.currentTimeMillis() - time));

        time = System.currentTimeMillis();
        for(int i = 0; i < max;i++)
        {
            LazySingleton.getInstance();
        }
        System.out.println("spend :"+(System.currentTimeMillis() - time));


        time = System.currentTimeMillis();
        for(int i = 0; i < max;i++)
        {
            StaticSingleton.getInstance();
        }
        System.out.println("spend :"+(System.currentTimeMillis() - time));



    }
           

結果如下:

java程式性能優化_設計優化_單例模式

有此可見,性能(1)(3),優于(2),當我們需要延長加載時(加快啟動速度),可以使用(3)來替代(2)。

(5)進階,在有對象被序列化,如何保證單例模式的對象唯一? 答案就是重寫readResolve()方法。具體代碼如下

class SerSingleton implements Serializable
{
    String name;

    private SerSingleton()
    {
        System.out.println("Singleton is create");

        name = "SerSingleton";
    }

    private static SerSingleton instance = new SerSingleton();


    public static SerSingleton getInstance()
    {
        return instance;
    }

    public static void createString()
    {
        System.out.println("createString in Singleton");
    }

    private Object readResolve()
    {
        //阻止新生成的新執行個體,總是傳回目前對象

        return instance;

    }

}