设计模式之享元模式

作者: ahking17 | 来源:发表于2017-03-01 18:12 被阅读221次
    应用场景

    享元模式指的是在项目中使用对象池. 可避免频繁的去创建某个类的对象, 大大减少创建的对象, 降低进程对内存的占用.
    最典型的场景是Android中的Message类, 一般情况下, app会频繁的大量使用Message对象, 如果每次都去new一个新对象出来使用, 用后再通过GC进行垃圾回收. 那很可能会导致频繁的gc,影响程序的性能.
    因此, android提供了一个Message对象池, 当开发者需要一个Message对象时, 调用Message.obtain()从这个池子里取一个对象出来使用, 这样做可以优化一定的性能.

    当要得到一个对象时, 推荐使用

    Message msg = Message.obtain();
    

    获得一个Message对象.
    而不要每次都

    Message msg = new Message();
    

    这样去创建一个新的Message对象去使用.

    Message的代码分析

    Message的对象池是通过一个链表实现的.
    默认最大长度是50,
    从链表中取对象时,取的是头节点.
    把不用的对象添加进链表, 也是作为头节点添加到链表中.

    public final class Message implements Parcelable {
        private static Message sPool; //指向Message对象池链表的头节点
        Message next; //指向链表头的下一个节点.
    
    
        private static final int MAX_POOL_SIZE = 50;
    
        public static Message obtain() {
            synchronized (sPoolSync) {
                if (sPool != null) { //如果链表存在的话
                    Message m = sPool; //取出链表的头节点对象, 并返回这个头节点对象
                    sPool = m.next;
                    m.next = null;
                    m.flags = 0; // clear in-use flag
                    sPoolSize--;
                    return m;
                }
            }
            return new Message();
        }
    
    
        public void recycle() {
            recycleUnchecked();
        }
    
    //对某一个不再使用的Message对象进行回收.
        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) {//链表长度小于50个的情况下
                    next = sPool;
                    sPool = this; //把当前要回收的节点作为链表头添加进链表
                    sPoolSize++;
                }
            }
        }
    
    }
    

    ---DONE.---

    相关文章

      网友评论

        本文标题:设计模式之享元模式

        本文链接:https://www.haomeiwen.com/subject/ocrcgttx.html