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对象, 以这种方式起到复用的效果!


Message源码分析的更多相关文章

  1. Android Handler机制(一)---Message源码分析

    Message: 定义: public final class Message implements Parcelable Message类是个final类,就是说不能被继承,同时Message类实现 ...

  2. Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue

    android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...

  3. RocketMQ 源码分析 —— Message 发送与接收

    1.概述 Producer 发送消息.主要是同步发送消息源码,涉及到 异步/Oneway发送消息,事务消息会跳过. Broker 接收消息.(存储消息在<RocketMQ 源码分析 —— Mes ...

  4. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  5. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  6. ABP源码分析四十二:ZERO的身份认证

    ABP Zero模块通过自定义实现Asp.Net Identity完成身份认证功能, 对Asp.Net Identity做了较大幅度的扩展.同时重写了ABP核心模块中的permission功能,以实现 ...

  7. MyCat源码分析系列之——前后端验证

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...

  8. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  9. 移动web app开发必备 - Deferred 源码分析

    姊妹篇  移动web app开发必备 - 异步队列 Deferred 在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码! 观察者模式 观察者模式( 又叫发布者-订阅者模 ...

  10. jQuery-1.9.1源码分析系列(十六)ajax——响应数据处理和api整理

    ajax在得到请求响应后主要会做两个处理:获取响应数据和使用类型转化器转化数据 a.获取响应数据 获取响应数据是调用ajaxHandleResponses函数来处理. ajaxHandleRespon ...

随机推荐

  1. 如何在Windows下使用WebMatrix+IIS开发PHP程序

    最近接收一个新项目,领导要求对客户端的接口采用PHP开发,为了方便,我就采用 Windows7专业版64位 + IIS7.5 + PHP5.5 + WebMatrix 作为开发环境进行开发: 首先下载 ...

  2. window监听节点改变的接口

    监听页面某个元素的属性变化 window.MutationObserver(callback) Mutation Observer API 用来监视 DOM 变动.比如节点的增减.属性的变动.文本内容 ...

  3. Vue 使用插件nprogress页面加载进度条

    下载 npm i nprogress 在main.js中引入: import App from './App' import VueRouter from 'vue-router' import ro ...

  4. TAP 交换机

    首发第一篇,就想分享一下TAP交换机的网络设备,为啥要谈这个呢,因为是一个冷门产品,大厂一般都没有,有也不作为重点产品推介,所以关注的人少,希望能给有这方面需求的人,又苦于找不到介绍资料的人以帮助.在 ...

  5. listener.log/listener_scan1.log监听日志太大清理

    listener_scan1.log清理lsnrctlset current_listener listener_scan1show log_statusset log_status offcd /u ...

  6. 自定义DOM事件函数封装

    非原生DOM触发,个性化定制的自定义事件. currentTarget(DOM对象):要触发事件的元素节点. type(字符串):触发的事件类型,例如"keydown". bubb ...

  7. typescript 的动态引入组件

    环境: Arco Pro + Vue3 vite自身对动态字符串形式的组件引入是有限制的, 以下写法会报错 官方文档中也对此有做说明, 只能通过固定形式去引用 以下形式不会报错, 但这种固定格式的局限 ...

  8. js对象深拷贝方法

    JSON.stringify()是目前前端开发过程中最常用的深拷贝方式, 原理是把有个对象序列化成为一个 JSON 字符串,将对象的内容转换成字符串的形式再保存到磁盘上, 再用 JSON.parse( ...

  9. tornado cgi wsgi uwsgi之间的关系

    Tornado可以当作HTTP server,直接TCP开始实现HTTP服务,这也就是为啥说Tornado可以不经过WSGI.实际上它也不是CGI. CGI是指通过stdin和stdout进行HTTP ...

  10. Thinkpad键盘操作手册与驱动 thinkpad蓝牙键盘KT-1525 manual

    thinklife mechanical keyboard tk500_win10.exe https://pan.baidu.com/s/1pQM3RcgV-phugew6vcKDLw