6種常見(jiàn)的單例模式


1.餓漢式

類(lèi)加載的時(shí)候就會(huì)初始化,他是線(xiàn)程安全的,但是類(lèi)加載的時(shí)候就初始化這樣會(huì)預(yù)先消耗一部分資源。

/**
 * Created by lijiayi on 2017/3/1.
 * 餓漢式單例
 */
public class Singleton {
    //生成單例對(duì)象
    private static final Singleton mSingleton = new Singleton();

    //私有化構(gòu)造方法
    private Singleton() {
    }

    //獲取單例對(duì)象
    public static Singleton getInstance() {
        return mSingleton;
    }
}



2.懶漢式

當(dāng)?shù)谝淮问褂玫臅r(shí)候才創(chuàng)建對(duì)象,合理占用資源,但是當(dāng)該對(duì)象已經(jīng)創(chuàng)建的時(shí)候,調(diào)用getInstance()方法會(huì)產(chǎn)生不必要的開(kāi)銷(xiāo),這是懶漢式的一個(gè)缺點(diǎn)。

/**
 * Created by lijiayi on 2017/3/1.
 * 懶漢式單例
 */
public class Singleton {
    //聲明單例對(duì)象
    private static Singleton mSingleton;

    //私有化構(gòu)造方法
    private Singleton() {
    }

    //同步該方法獲取單例對(duì)象
    public static synchronized Singleton getInstance() {
        //當(dāng)該對(duì)象為空的時(shí)候創(chuàng)建該對(duì)象
        if (mSingleton == null) {
            mSingleton = new Singleton();
        }
        //返回該對(duì)象實(shí)例
        return mSingleton;
    }
}


3.DCL式

該方式能保證在需要的時(shí)候才初始化單例,又能夠保證線(xiàn)程安全,而且單例初始化后調(diào)用getInstance()不會(huì)進(jìn)行同步鎖。

/**
 * Created by lijiayi on 2017/3/1.
 * DCL單例
 */
public class Singleton {
    //聲明單例對(duì)象
    private static Singleton mSingleton;

    //私有化構(gòu)造方法
    private Singleton() {
    }

    //同步該方法獲取單例對(duì)象
    public static synchronized Singleton getInstance() {
        //當(dāng)該對(duì)象為空的時(shí)候先同步這個(gè)對(duì)象
        if (mSingleton == null) {
            synchronized (Singleton.class) {
                //再判斷是否為空
                if (mSingleton == null) {
                    //如果還空的話(huà) 就創(chuàng)建對(duì)象
                    mSingleton = new Singleton();
                }
            }
        }
        //返回該對(duì)象實(shí)例
        return mSingleton;
    }
}

4.靜態(tài)內(nèi)部類(lèi)式

該方式保證了資源預(yù)先消耗、不必要的同步、線(xiàn)程的安全問(wèn)題,還避免了DCL模式在某些情況下失效的問(wèn)題。所以筆者建議使用該單例模式。

/**
 * Created by lijiayi on 2017/3/1.
 * 靜態(tài)內(nèi)部類(lèi)單例
 */
public class Singleton {

    //私有化構(gòu)造方法
    private Singleton() {
    }

    //獲取單例對(duì)象 
    public static Singleton getInstance() {
        //返回內(nèi)部類(lèi)中的singleton對(duì)象 
        return SingletonHolder.singleton;
    }

    /**
     * 靜態(tài)內(nèi)部類(lèi)
     * 第一次加載類(lèi)的時(shí)候不用調(diào)用該類(lèi),創(chuàng)建singleton對(duì)象,
     * 只有調(diào)用getInstance()方法時(shí)才會(huì)創(chuàng)建該對(duì)象。
     */
    private static class SingletonHolder {
        private static final Singleton singleton = new Singleton();
    }

}

5.枚舉式

枚舉是線(xiàn)程安全的,而且任何情況下都是一個(gè)實(shí)例,他不能被序列化,也不能被反射,所以枚舉單例也是一個(gè)不錯(cuò)的選擇。



/**
 * Created by lijiayi on 2017/3/1.
 * 枚舉式單例
 * 枚舉單例時(shí)線(xiàn)程安全的,在任何情況下都是一個(gè)單例
 */
public enum SingletonEnum {
    //枚舉的類(lèi)型
    INSTANCE;

    // 單例中的函數(shù)
    public void todoSomethings() {
        System.out.println("do somethings");
    }
}

//枚舉單例的使用
SingletonEnum.INSTANCE.todoSomethings();```
***
###6.容器實(shí)現(xiàn)單例
它的好處是可以統(tǒng)一的管理單例,安卓中g(shù)etSystemService(String name)就是用這種方式實(shí)現(xiàn)的。
``` java 
/**
 * Created by lijiayi on 2017/3/1.
 * 容器模式單例
 * 實(shí)現(xiàn)了程序中單例的統(tǒng)一管理
 */
public class SingletonManager {
    private static Map<String, Object> singletonManagerMap = new HashMap<String, Object>();

    //私有化構(gòu)造方法
    private SingletonManager() {

    }

    //注入程序中的單例
    public static void registerSingleton(String key, Object instance) {
        if (!singletonManagerMap.containsKey(key)) {
            singletonManagerMap.put(key, instance);
        }
    }

    //獲取對(duì)于key值的單例對(duì)象
    public static Object getInstance(String key) {
        return singletonManagerMap.get(key);
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容