設(shè)計(jì)模式之享元模式

應(yīng)用場(chǎng)景

享元模式指的是在項(xiàng)目中使用對(duì)象池. 可避免頻繁的去創(chuàng)建某個(gè)類(lèi)的對(duì)象, 大大減少創(chuàng)建的對(duì)象, 降低進(jìn)程對(duì)內(nèi)存的占用.
最典型的場(chǎng)景是Android中的Message類(lèi), 一般情況下, app會(huì)頻繁的大量使用Message對(duì)象, 如果每次都去new一個(gè)新對(duì)象出來(lái)使用, 用后再通過(guò)GC進(jìn)行垃圾回收. 那很可能會(huì)導(dǎo)致頻繁的gc,影響程序的性能.
因此, android提供了一個(gè)Message對(duì)象池, 當(dāng)開(kāi)發(fā)者需要一個(gè)Message對(duì)象時(shí), 調(diào)用Message.obtain()從這個(gè)池子里取一個(gè)對(duì)象出來(lái)使用, 這樣做可以優(yōu)化一定的性能.

當(dāng)要得到一個(gè)對(duì)象時(shí), 推薦使用

Message msg = Message.obtain();

獲得一個(gè)Message對(duì)象.
而不要每次都

Message msg = new Message();

這樣去創(chuàng)建一個(gè)新的Message對(duì)象去使用.

Message的代碼分析

Message的對(duì)象池是通過(guò)一個(gè)鏈表實(shí)現(xiàn)的.
默認(rèn)最大長(zhǎng)度是50,
從鏈表中取對(duì)象時(shí),取的是頭節(jié)點(diǎn).
把不用的對(duì)象添加進(jìn)鏈表, 也是作為頭節(jié)點(diǎn)添加到鏈表中.

public final class Message implements Parcelable {
    private static Message sPool; //指向Message對(duì)象池鏈表的頭節(jié)點(diǎn)
    Message next; //指向鏈表頭的下一個(gè)節(jié)點(diǎn).


    private static final int MAX_POOL_SIZE = 50;

    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) { //如果鏈表存在的話
                Message m = sPool; //取出鏈表的頭節(jié)點(diǎn)對(duì)象, 并返回這個(gè)頭節(jié)點(diǎn)對(duì)象
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }


    public void recycle() {
        recycleUnchecked();
    }

//對(duì)某一個(gè)不再使用的Message對(duì)象進(jìn)行回收.
    void recycleUnchecked() {
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        what = 0;
        arg1 = 0;
        arg2 = 0;
        obj = null;
        replyTo = null;
        sendingUid = -1;
        when = 0;
        target = null;
        callback = null;
        data = null;

        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {//鏈表長(zhǎng)度小于50個(gè)的情況下
                next = sPool;
                sPool = this; //把當(dāng)前要回收的節(jié)點(diǎn)作為鏈表頭添加進(jìn)鏈表
                sPoolSize++;
            }
        }
    }

}

---DONE.---

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,334評(píng)論 25 708
  • 享元模式 由于對(duì)象創(chuàng)建的開(kāi)銷(xiāo),面向?qū)ο蟮南到y(tǒng)可能會(huì)面臨性能問(wèn)題。性能問(wèn)題通常在資源受限的嵌入式系統(tǒng)中出現(xiàn),比如智能...
    英武閱讀 1,822評(píng)論 0 50
  • 引入享元模式 享元模式的實(shí)例 享元模式的分析 引入享元模式 flyweight是輕量級(jí)的意思,指的是拳擊比賽中選手...
    六尺帳篷閱讀 711評(píng)論 0 2
  • 她這樣說(shuō),我們可不會(huì)真的動(dòng)氣,現(xiàn)在要的是心平氣和。鎮(zhèn)定,冷靜,對(duì)付她。 她不同于之前的任何人。她給我們的壓力,大過(guò)...
    浮生萬(wàn)夢(mèng)星耀燭天閱讀 1,655評(píng)論 0 1
  • 文 | 正一 2017 要投入 在即興劇中,除了game之外的所有點(diǎn)都應(yīng)演得真實(shí)可信。如你把其他點(diǎn)都做得極好,唯獨(dú)...
    盧正一閱讀 785評(píng)論 0 2