還為那些設(shè)計(jì)模式煩惱嗎-單例模式

1、懶漢模式:

public class Singleton {
    private static Singleton mSingleton;

    private Singleton() {
    }

    /**
     * 
     * 線程安全
     * 
     * @return
     */

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

    /**
     * 線程不安全
     * 
     * @return
     */
    /*public static Singleton getInstance() {
        if (mSingleton == null) {
            mSingleton = new Singleton();
        }
        return mSingleton;
    }*/
}

特點(diǎn):

優(yōu)點(diǎn):?jiǎn)卫挥性谑褂玫臅r(shí)候才會(huì)被實(shí)例化,在一定程序上節(jié)約了資源
缺點(diǎn):第一次加載時(shí)需要及時(shí)進(jìn)行實(shí)例化,反應(yīng)稍慢,最大的問題是每次調(diào)用getInstance都進(jìn)行同步,行成不必要的同步開銷。這種模式一般不建議使用。

2、餓漢模式:

public class Singleton {
    private static final Singleton mSingleton = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return mSingleton;
    }
}

特點(diǎn):

優(yōu)點(diǎn):沒有加鎖,執(zhí)行效率會(huì)提高。
缺點(diǎn):類加載時(shí)就初始化,浪費(fèi)內(nèi)存。

3、雙重檢查加載

public class Singleton {
    private volatile static Singleton mSingleton = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (mSingleton == null) {
            synchronized (Singleton.class) {
                if (mSingleton == null) {
                    mSingleton = new Singleton();
                }
            }
        }
        return mSingleton;
    }
}

特點(diǎn):

優(yōu)點(diǎn):資源利用率高,第一次執(zhí)行g(shù)etInstance時(shí)單例對(duì)象才會(huì)被實(shí)例化,效率高
缺點(diǎn):第一次加載時(shí)反應(yīng)稍慢,而且volatile或多或少會(huì)影響到性能。

4、靜態(tài)內(nèi)部類

public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.mSingleton;
    }

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

}

特點(diǎn):

當(dāng)?shù)谝淮渭虞dSingleton類時(shí)并不會(huì)初始化mSingleton,只能第一次調(diào)用getInstance方法時(shí)才會(huì)導(dǎo)致mSingleton被初始化。因此,第一次調(diào)用getInstance方法會(huì)導(dǎo)致虛擬機(jī)加載SingletonHolder類,這種方式不僅能確保安全,也能保證單例對(duì)象的唯一性,同時(shí)也延遲了單例的實(shí)例化。推薦性使用該實(shí)現(xiàn)方式;

5、枚舉

public enum SingletonEnum {
    SINGLETON;
}

特點(diǎn):

寫法簡(jiǎn)單,線程安全,能杜絕單例對(duì)象在被反序列化的重新生成新的對(duì)象

注意:除了枚舉,上面幾種單例模式如果想杜絕單例對(duì)象在被反序列化的重新生成新的對(duì)象,要實(shí)現(xiàn)Serializable接口
private Object readResolve() throws ObjectStreamException {    
        return SingletonHolder.mSingleton;  
}

6、使用容器實(shí)現(xiàn)單例模式

public class SingletonManager {
    private static Map<String, Object> mSingletonManager = new HashMap<String, Object>();

    private SingletonManager() {
    }

    public static void addSingletonToMangager(String key, Object singleton) {
        if (!mSingletonManager.containsKey(key)) {
            mSingletonManager.put(key, singleton);
        }
    }

    public static Object getSingletonFromManager(String key) {
        return mSingletonManager.get(key);
    }
}

特點(diǎn):

在程序的初始,將多種單例類型注入到一個(gè)統(tǒng)一的管理類中,在使用時(shí)根據(jù)key獲取對(duì)象對(duì)應(yīng)類型的對(duì)象,這使我們可以管理多種類型的單例,并且使用時(shí)可以通過統(tǒng)一的接口進(jìn)行獲取。

總結(jié)

1、構(gòu)造函數(shù)不對(duì)外開放,private;
2、通過一個(gè)靜態(tài)方法或者枚舉返回單例類對(duì)象;
3、確保單例類的對(duì)象有且只有一個(gè),尤其是在多線程環(huán)境下;
4、確保單例類對(duì)象在反序列化時(shí)不會(huì)重新構(gòu)建對(duì)象。

?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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