美文网首页
Handler源码学习(二)Message对象池

Handler源码学习(二)Message对象池

作者: 黑丫山上小旋风 | 来源:发表于2016-07-20 17:51 被阅读174次

    Handler源码学习(一)流程
    Handler源码学习(二)Message对象池
    Handler源码学习(三)MessageQueue入队插队
    消息池是全系统共用,上限为50个

    private static final int MAX_POOL_SIZE = 50;
    
    // sometimes we store linked lists of these things
    /*package*/ Message next;
    private static Message sPool;
    
    //假设现在消息池为空,从new message开始,到这个message被取出使用后,准备回收
    //准备工作:拿到同步锁,避免线程不安全
    //1.next = sPool,因为池中是空的,所以此时sPool其实是null
    //2.spool = this,将当前这个message作为池中中下一个应该被复用的对象
    //3.sPoolSize ++;将池子中的数量增加一,这个数量依然是全系统共享
    void recycleUnchecked() {
            synchronized (sPoolSync) {
                if (sPoolSize < MAX_POOL_SIZE) {
                    next = sPool;
                    sPool = this;
                    sPoolSize++;
                }
            }
        }
    //上面已经回收了一个message,在这里来获取message,看看会发生什么
    //同样进入同步代码块
    //1.判断sPool是否是为空,如果池子为空,就直接new一个message
    //上面已经回收过一个message了,这里应该不为空
    //m =sPool;把池子里的这个message取出来
    //2.sPool = m.next 将池中下一个复用的对象赋值为m.next,但是我们通过上面的代码发现这个是null,先
    //不管
    //3.将m.next置为空,m.flags = 0 给了一个标记使用中
    //4.从池子中减去
    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();
    }
    

    上面的过程只有一个mesage,详细解释一下sPool和next,将sPool看成一个指针,通过next来将对象组成了一个链表,因为每次只需要从池子里拿一个对象,所以不需要关心池子里具体有多少个对象,而是拿出当前这个sPool所指向的这个对象就可以了,sPool从思路上理解就是通过左右移动来完成复用和回收

    Obtain() -- 复用

    MessageObtain(1).jpg

    当调用Obtain()的时候让sPool=next,因为第一个message.next就等于第二个message,从图上看相当于sPool这个指针向后移动了一位,随后会将第一个message.next的值置为空
    ![Uploading MessageRecycle_209561.jpg . . .]

    如下图


    MessageObtain(2).jpg

    现在这个链表看上去就断了,如果in-use这个message使用完毕了,怎么回到链表中?

    recycleUnchecked() -- 回收

    再看回收的方法中的代码,next = sPool,将当前sPool所指向的message对象赋值给in-use的next,然后sPool = this,将sPool指向第一个message对象


    MessageRecycle.jpg

    这样,就将链表又恢复了~,而且不管是复用还是回收都是保证线程同步的,所以始终会形成一条链式结构

    相关文章

      网友评论

          本文标题:Handler源码学习(二)Message对象池

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