zoukankan      html  css  js  c++  java
  • Message源码分析

    Message 在Android中主要是在 消息循环机制 中使用,即配合 Handler,LooperMessageQueue来进行线程切换,线程间传递数据。Message存储了我们所有需要的东西。

    还可以配合Handler在IPC中传递数据。

    我们在使用的过程中应该使用obtain()这个方法来重复利用消息池里面的Message

    而复用池本质上就是一个单向链表,为了更好的理解,Message复用池的实现,我们先来看下,简单的单向链表实现.

    public final class Message implements Parcelable {
        ...
        // 下一个节点的引用
        Message next;
        // 这里起到类锁的功能,相当于 Message.class
        private static final Object sPoolSync = new Object();
        // 可以类比为 头结点
        private static Message sPool;
        // 链表的长度
        private static int sPoolSize = 0;
        // 链表的最大长度
        private static final int MAX_POOL_SIZE = 50;
        // 获取Message对象,类比单向链表的removeHead操作
        public static Message obtain() {
            // 同步锁, 这里相当于锁住 Message.class, 起到类锁的作用, 每一个Message实例都是同一把锁
            synchronized (sPoolSync) {
                // 链表中有可复用的Message,直接拿到头结点,然后将头结点指向下一个元素
                if (sPool != null) {
                    Message m = sPool;
                    sPool = m.next;
                    m.next = null;
                    m.flags = 0; // clear in-use flag
                    sPoolSize--;
                    return m;
                }
            }
            // 链表中,没有可复用的message,直接new
            return new Message();
        }
        // 类比单向链表的insertHead操作
        void recycleUnchecked() {
            // 清空数据操作
            obj = null;
            ...
            // 同步锁
            synchronized (sPoolSync) {
                // 如果链表长度小于50,将当前结点,加入链表头部
                if (sPoolSize < MAX_POOL_SIZE) {
                    next = sPool;
                    sPool = this;
                    sPoolSize++;
                }
            }
        }
        ...
    }

    从上面的分析,我们来梳理一下整体的流程思想.

    • Message 使用一个静态变量,来起到头结点的作用.

    静态变量属于类变量,内存中只会存在一份引用,正好能起到 头结点的作用

    • Message 将自身作为Node节点,存储下一个节点的引用,和自身数据
    • obtain()方法相当于链表中移除首元素,并返回该元素的操作

    从复用池中获取Message避免了 new创建的消耗.

    • recycleUnchecked()方法相当于链表中将节点加入到头部的操作

    添加到复用池之前,会先将Message中的数据清空.

    • Message添加了线程安全的操作
    • Message复用池最多保存50个使用完待复用的Message

    50个可能是考虑到内存开销和时间开销的平衡, 不是将数据无限制的添加到复用池.


    Message将自身作为节点, 使用一个静态变量作为头结点,让Message自身形成一个链表,而链表中存的是 已经清空数据的Message对象, 以这种方式起到复用的效果!


  • 相关阅读:
    《何以为家》--观影心得
    博弈论 -- 巴什博弈
    《黑客攻防技术-系统实战》第二章--栈溢出1
    《汇编语言》--程序范例
    《黑客攻防技术-系统实战》开篇讲解
    ptrace理解
    DPDK初始化
    C++ 对象内存模型
    DPDK学习路线计划
    DPDK学习开篇
  • 原文地址:https://www.cnblogs.com/lianzhen/p/12925206.html
Copyright © 2011-2022 走看看