你知道Message.obtain()什么原理吗?
你经常调用Message.obtain()来复用一个Message对象吧?有看过内部实现吗?
我…[污]
Message.obtain()可以返回一个可循环使用的Message对象,那思考以下几个问题:
1、Message.obtain 返回的Message是哪来的?
2、Message.obtain 返回的对象是怎么存储的?
3、可循环使用的Message对象 和 普通Message对象有什么区别?
4、Message对象的存储池配置了多大?超过上限会弹性扩充吗?
解题[舔屏]:
1、 Message.obtain 返回的Message是哪来的?
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();
}
源码一看,我擦 真简单,要不就是 sPool对象,要不就是new Message()。
new就不说了,sPool是个啥?
private static Message sPool;
它也是个Message?,那m.next是?
// sometimes we store linked lists of these things
@UnsupportedAppUsage
/package/ Message next;
没错,自链表实现,要不就是new出来的,要不就去取 上次储的sPool。
2、Message.obtain 返回的对象是怎么存储的?
我们刚看到,sPool主要是别人储起来的,那是谁存起来的呢?追代码。
/**
* Recycles a Message that may be in-use.
* Used internally by the MessageQueue and Looper when disposing of queued Messages.
*/
@UnsupportedAppUsage
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 = UID_NONE;
workSourceUid = UID_NONE;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this; //这里赋的值sPoolSize++;}}
}
soga,原来是这里,那这破方法是,内部方法,谁调的呢?
/**
* Return a Message instance to the global pool.
*
* You MUST NOT touch the Message after calling this function because it has
* effectively been freed. It is an error to recycle a message that is currently
* enqueued or that is in the process of being delivered to a Handler.
*
*/
public void recycle() {
if (isInUse()) {
if (gCheckRecycle) {
throw new IllegalStateException("This message cannot be recycled because it "
+ “is still in use.”);
}
return;
}
recycleUnchecked();
}
soga,原来有一个 open 的recycle,到这里 貌似 串起来了,我们自己new,然后自己recycle,然后自己obtain,完事!
3、可循环使用的Message对象 和 普通Message对象有什么区别?
看了这么多源码,可以确定,它们是一回事。
4、Message对象的存储池配置了多大?超过上限会弹性扩充吗?
这是个好问题,如果我们创建一堆的Message,都调用recycle,那这链表不就无限长了?Message就回收不了了,总有一天会oom。
那主要看回收部份。
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
哈,有个上限 MAX_POOL_SIZE,那定义了多少?
public static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
看到了,50,也就是说,缓存了50个Messge,我就不再缓存了。所以没有 弹性扩充 的问题。
别走客官,如果…
1、这玩意使用到了对象锁,在多线程竞争中,必然效率低下,你还有没有更好的Message循环利用方式,可以代替synchronized呢?
2、这种循环利用方法,你叫它什么设计模式呢?
3、我擦,我之前只用Message.Obtain(),从来不调message.recycle()。(逃~)
欢迎留言、分享、转发,一键三连。
三连的人很酷酷酷酷酷酷~~[坏笑]
你知道Message.obtain()什么原理吗?相关推荐
- 关于在用异步消息处理机制使用Message.Obtain()方法(而非New Message)获得一个Message对象的好处
类概述 定义一个包含任意类型的描述数据对象,此对象可以发送给Handler.对象包含两个额外的int字段和一个额外的对象字段,这样可以使得在很多情况下不用做分配工作. 尽管Message的构造器是公开 ...
- Handler基本使用(二)new Message 、 Handler.obtainMessage和Message.obtain
通常使用handler发送信息时,会使用下面两种方式 //方法1Message msg = new Message();msg.what = 1;msg.arg1 = 2;msg.arg2 = 3;m ...
- C语言handler类作用,Handle的原理(Looper、Handler、Message三者关系)
转载请注明出处:http://blog.csdn.net/lowprofile_coding/article/details/72580044 介绍 前面的内容对Handler做了介绍,也讲解了如何使 ...
- Handle的原理(Looper、Handler、Message三者关系)
转载请注明出处:http://blog.csdn.net/lowprofile_coding/article/details/72580044 介绍 前面的内容对Handler做了介绍,也讲解了如何使 ...
- Message中obtain()与recycle()
Message中obtain()与recycle() 原文:链接 在obtain的所有重载方法中,第一行都是Message m = obtain();,即调用空参的方法. 先来看一下这个空参方法 pu ...
- Android刷新机制-View绘制原理
Android刷新机制-View绘制原理 Android刷新机制-SurfaceFlinger原理 Android刷新机制-Choreographer原理 一.概述 本文将从startActivity ...
- android handler的机制和原理_一文搞懂handler:彻底明白Android消息机制的原理及源码
提起Android消息机制,想必都不陌生.其中包含三个部分:Handler,MessageQueue以及Looper,三者共同协作,完成消息机制的运行.本篇文章将由浅入深解析Android消息机制的运 ...
- Android 插件化原理学习 —— Hook 机制之动态代理
前言 为了实现 App 的快速迭代更新,基于 H5 Hybrid 的解决方案有很多,由于 webview 本身的性能问题,也随之出现了很多基于 JS 引擎实现的原生渲染的方案,例如 React Nat ...
- Android Handler与Looper原理简析
一直感觉自己简直就是一个弱智,最近越来越感觉是这样了,真的希望自己有一天能够认同自己,认同自己. 本文转载于:https://juejin.im/post/59083d7fda2f60005d14ef ...
- Android Handler的原理
简介 在 Android 中,只有主线程才能操作 UI,但是主线程不能进行耗时操作,否则会阻塞线程,产生 ANR 异常,所以常常把耗时操作放到其它子线程进行.如果在子线程中需要更新 UI,一般是通过 ...
最新文章
- 前端面试查漏补缺--(一) 防抖和节流
- 打包解决方案后,安装时提示只能在IIS5.1以上运行解决方法
- Mysql Explain 详解
- [ Python ] PIL
- 代码UITableView点击cell跳转
- 单链表的整表创建以及整表删除
- java监听网络连接_Android RxJava 之网络链接监听示范
- CentOS6离线升级CentOS7
- java延迟队列,java高级面试笔试题
- 关于电脑程序员职务 用英语怎么表达
- java语言是那年_Java语言是在()年正式推出的_学小易找答案
- NOIP2017 D2T1 奶酪
- 20160801java学习重点:函数
- JDK自带的native2ascii工具完全揭密
- MATLAB基本语法速成
- 日志管理系统,多种方式总结
- 简述java工厂模式详解_JAVA 设计模式之 工厂模式详解
- 零基础入门网络,静态LACP链路捆绑详解,带宽扩容,链路冗余备份
- pylint高频警告错误的原因及处理建议
- 详解ORACLE数据库的分区表
热门文章
- win10网络显示已连接到服务器异常,w10 网络连接配置异常如何修复
- 迷你世界服务器为什么在维护,迷你世界为什么进不去迷你世界进不去怎么办
- w10系统打不开服务器共享打印机,共享打印机拒绝访问怎么办?Win10打印机无法共享的解决办法...
- 小程序怎么接入第三方客服工具?
- SQL 事务(Tran | Transation)与 Try...Catch 的使用
- R、冗余分析(RDA)、ggplot2、置信椭圆
- android 图片 3d 动画,DEMO:transition3d、运用动画实现图片3d翻转效果
- 计算机键盘上的句号键在哪,电脑键盘句号是哪个键
- Vue.js实现文章评论和回复评论功能
- WPS自动生成目录,目录里显示图片如何解决