-
时序图异步消息和同步消息画法
2020-12-04 09:36:59 -
Android 消息屏障与异步消息
2020-11-03 22:35:21其中消息屏障和异步消息搭配使用,可以达到屏蔽普通消息、优先处理异步消息的目的。 ##「目录:」 如何插入一个消息屏障? 如何删除一个消息屏障? 如何插入一个异步消息? 消息屏障对插入消息有什么影响? 消息...作者:Ahab
Android 消息机制中的 MessageQueue 可以存放三种类型的消息,普通消息、消息屏障和异步消息。其中消息屏障和异步消息搭配使用,可以达到屏蔽普通消息、优先处理异步消息的目的。
##「目录:」
- 如何插入一个消息屏障?
- 如何删除一个消息屏障?
- 如何插入一个异步消息?
- 消息屏障对插入消息有什么影响?
- 消息屏障是如何优先处理异步消息的?
- Framework 中哪里使用了消息屏障?
1. 如何插入一个消息屏障?
见 MessageQueue 的 postSyncBarrier 方法:
private int postSyncBarrier(long when) { synchronized (this) { final int token = mNextBarrierToken++; final Message msg = Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token; //按时间排序插入到队列中... return token; } }
- 消息屏障不需分发处理,没有 target Handler,后续也会根据有无 target 来判断是否为消息屏障
- 消息屏障也是有时间戳的,并且只会对后面的消息起到屏障作用,不会影响前面的消息
- 消息屏障插入后无需唤醒线程,因为消息屏障原本的目的就是打算屏蔽消息处理的
- 插入后会返回一个 token,用于后续移除指定 token 的消息屏障
- 方法为 private,外部调用需反射
2. 如何删除一个消息屏障?
见 MessageQueue 的 removeSyncBarrier 方法:
public void removeSyncBarrier(int token) { synchronized (this) { Message prev = null; Message p = mMessages; while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } //从队列中删除这个消息屏障... if (needWake && !mQuitting) { nativeWake(mPtr); } } }
- 根据无 target 及 token 匹配找到对应的消息屏障
- 删除屏障后可能需要唤醒线程,是否唤醒取决于当前是否是因为消息屏障而阻塞的
3. 如何插入一个异步消息?
Message 的 setAsynchronous 为开放 API,直接调用设置即可,比如在 ViewRootImpl 中对输入事件的处理:
public void dispatchInputEvent(InputEvent event, InputEventReceiver receiver) { SomeArgs args = SomeArgs.obtain(); args.arg1 = event; args.arg2 = receiver; Message msg = mHandler.obtainMessage(MSG_DISPATCH_INPUT_EVENT, args); msg.setAsynchronous(true); //异步消息 mHandler.sendMessage(msg); }
由于输入事件需要快速响应,优先级比较高,所以设置为异步消息,避免被消息屏障屏蔽掉
4. 消息屏障对插入消息有什么影响?
见 MessageQueue 的 enqueueMessage 方法:
//省略部分代码... Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { //插入到队列头部 msg.next = p; mMessages = msg; needWake = mBlocked; } else { //插入到队列中间 needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; prev.next = msg; } if (needWake) { //唤醒 nativeWake(mPtr); }
- 如果插入到队列头部,那么只要当前线程是休眠的,就要唤醒,不管有没有消息屏障,因为消息屏障不会影响在它之前的消息
- 如果插入到队列中间且队列头消息为消息屏障,那还要判断插入的消息是不是最早的异步消息,如果是才唤醒线程。因为如果之前已经有异步消息,那说明已经对之前的异步消息做过唤醒或休眠指定时间的处理了,不用再此唤醒
5. 消息屏障是如何优先处理异步消息的?
见 MessageQueue 的 next 方法:
Message next() { //省略部分代码... for (;;) { nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } //省略部分代码... }
- 如果当前消息不是消息屏障,那异步消息和普通消息无异,都会按照时间排序依次执行
- 如果当前消息为消息屏障,就会去找队列中的异步消息,如果没有异步消息,就无限休眠;如果有,就根据这个异步消息的处理时间去分发处理或休眠
6. Framework 中哪里使用了消息屏障?
ViewRootImpl 中界面绘制时使用了消息屏障:
void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; //插入一个消息屏障,屏蔽普通消息的处理 mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); } } void doTraversal() { if (mTraversalScheduled) { mTraversalScheduled = false; //移除消息屏障 mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); } }
与输入事件一样,界面绘制也是优先级高的消息,需要优先处理,所以这里插入消息屏障 block 其他普通消息,以达到优先处理界面绘制的目的。
喜欢本文的话,不妨顺手给我点个小赞、评论区留言或者转发支持一下呗😜😜😜~
点击【GitHub】还有彩蛋哦!!! -
delphi 异步消息通知
2015-04-27 17:36:11异步消息通知 消息队列 发送队列 接口实现 -
同步消息和异步消息
2020-08-15 12:18:23同步消息和异步消息区别 两者使用场景不一样,比如说A给B发送一封电子邮件,A是不需要知道B是否收到就可以了的,把自己的信息传达出去,这样的场景就是异步消息。因为在这个过程中A在乎的是把某件事情传达出去就...同步消息和异步消息区别
两者使用场景不一样,比如说A给B发送一封电子邮件,A是不需要知道B是否收到就可以了的,把自己的信息传达出去,这样的场景就是异步消息。因为在这个过程中A在乎的是把某件事情传达出去就可以,而不必在乎其他人的状态,比如张贴告示也是这样,不需要知道每个人都是否知道这则告示的内容,而是张贴出去让大家基本知晓就可以。如果在付款的时候,A已经付款了,这个时候如果没有收到支付成功的状态提示的话就会在想自己是否已经支付成功了呢?就会一直处于等待状态,直到系统反馈一个消息,要么是支付成功要么是支付失败才回进行后续的操作。这样的两个例子就能很简单的区分同步消息和异步消息了。
-
同步消息和异步消息区别
2020-12-15 12:45:50同步消息和异步消息 同步消息和异步消息区别 两者使用场景不一样,比如说A给B发送一封电子邮件,A是不需要知道B是否收到就可以了的,把自己的信息传达出去,这样的场景就是异步消息。因为在这个过程中A在乎的是把某...同步消息和异步消息
同步消息和异步消息区别
两者使用场景不一样,比如说A给B发送一封电子邮件,A是不需要知道B是否收到就可以了的,把自己的信息传达出去,这样的场景就是异步消息。因为在这个过程中A在乎的是把某件事情传达出去就可以,而不必在乎其他人的状态,比如张贴告示也是这样,不需要知道每个人都是否知道这则告示的内容,而是张贴出去让大家基本知晓就可以。如果在付款的时候,A已经付款了,这个时候如果没有收到支付成功的状态提示的话就会在想自己是否已经支付成功了呢?就会一直处于等待状态,直到系统反馈一个消息,要么是支付成功要么是支付失败才回进行后续的操作。这样的两个例子就能很简单的区分同步消息和异步消息了。
参考文献:
-
【Android】消息队列之异步消息
2020-06-05 20:31:27异步消息可以理解为是用来提升消息的重要性,在有异步消息时,会优先处理距当前时间最近的异步消息,同步消息都不会被处理,绘制界面就是一个异步消息; 同步消息:没有设置为异步的消息都是同步消息; Message... -
DotNet异步消息处理
2019-09-24 07:12:55在异步消息处理中,启动任务的方法被立即返回而不等待结果。应用程序可以在任务完成过程中继续它原来的工作。任务完成时,服务器可以通知应用程序消息已被成功处理。 有两种类型的异步消息处理操作:异步接收消息... -
Android异步消息处理机制完全解析,带你从源码的角度彻底理解
2013-08-22 14:02:45我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,...这种处理方式被称为异步消息处理线程,虽然我相信大家都会用,可是你知道它背后的原理是什么样的吗?今天我们就来一起深入探究一下Handler和 -
RocketMQ同步消息、异步消息、单向消息详解
2020-05-07 10:48:25一、RocketMQ 支持 3 种消息发送方式 : ...2、异步消息(async message) producer向 broker 发送消息时指定消息发送成功及发送异常的回调方法,调用 API 后立即返回,producer发送消息线程不阻塞 ,... -
简单消息,异步消息,同步消息辨析
2016-12-02 10:35:26简单消息,异步消息,同步消息辨析 附例子 -
javaEE 异步消息处理
2012-07-21 20:16:48javaEE 异步消息处理 服务端与客户端 1、客户端发送请求 服务端响应请求发送消息 客户端接受消息 2、过程:服务端一直发送消息 客户端一直接受放入容器里 容器里用线程去处理 -
ceph异步消息类图
2016-11-09 10:11:35ceph异步消息类图 -
异步消息及使用ActiveMQ发送消息
2018-08-21 21:01:08一,异步消息 像RMI和Hession/Burlap这些远程调用机制都是同步的,当客户端调用远程方法时,客户端必须等到远程方法完成后,才可以继续执行,但是有些操作是不需要等待,这时就可以用异步消息。 有两个主要... -
Android 异步消息机制
2016-08-11 12:00:18Android 异步消息机制 -
Android异步消息处理机制
2017-09-11 18:57:041、异步消息处理机制 学习Android异步消息机制之前,我们需要搞懂这么几个问题: ·什么是异步消息处理 ·为什么需要异步消息处理 ·怎么实现异步消息处理 什么是异步消息处理: 所谓的异步机制,是指在... -
异步消息处理机制
2018-03-18 10:18:00因为Android不允许在子线程中进行更新UI,异步消息处理机制来解决这个问题。 Android中的异步消息处理由4部分组成:Message,Handler,MessageQueue和looper。 Message:传递消息 Handle:发送,处理信息 Message... -
Android处理异步消息
2019-04-08 11:45:31Android处理异步消息一、目标二、体验地址三、功能设计四、实现方案1. 基础方案2. 进阶方案3. 高级方案4. 取消异步任务五、举个例子六、Finally 一、目标 处理异步任务,并提供用户进度反馈。 二、体验地址 神马... -
小米王晓宇:电商异步消息系统的实践
2016-05-10 15:27:14电商异步消息系统实践视频教程,该课程重点介绍Notify异步消息系统的设计细节与工作原理,以及所解决的技术与业务问题。并且会结合小米网的业务发展以及系统架构的变迁,介绍相应的架构变化以及所遇到的问题的解决... -
异步消息的原理
2017-05-19 10:15:00异步消息的目的:处理系统之间的通信。异步指的是消息发送者无需等待消息接收者的处理和返回。 在异步消息的体系中,有两个重要角色: 1.消息代理(Broker)2:目的地(Destination) 当发送者发出消息后,消息将... -
异步消息最终一致型
2019-01-03 20:17:35异步消息最终一致型 -
Android 异步消息处理机制
2017-10-19 14:28:35异步消息处理机制 -
从ActiveMQ异步消息异步调用的区别到线程池的总结
2019-12-30 17:54:51ActiveMQ的异步消息 MQ的异步消息指的不是必须每生产一次就消费一次。生产方只要放到消息通道里。消费方不断地去监听就可以了。异步消息可以使用JMS来编码操作。JMS本身就是异步的。直接标注上代码即可。 首先... -
C#socketUdp异步消息发送接收
2015-06-12 15:12:48C# socketUdp 异步 消息发送接收 -
Android 异步消息处理
2017-10-31 09:28:56前言 方法总结 使用Handler 使用runInUiThread方法 使用AsyncTask 后记前言 我们都知道Android的UI线程是不安全,在子线程中更新UI会...我们再来把异步消息处理的整个流程梳理一下:首先需要在主线程当中创建一个Han -
同步消息和异步消息传递的区别?
2018-10-23 00:26:47同步与异步消息的区别 1、同步消息 同步消息传递涉及到等待服务器响应消息的客户端。消息可以双向地向两个方向流动。本质上,这意味着同步消息传递是双向通信。即发送方向接收方发送消息,接收方接收此消息并... -
async task 异步消息
2014-11-26 09:27:21async task 异步消息 -
RocketMQ〖三〗消息发送,同步消息,异步消息,单向消息,消息消费
2020-02-11 00:44:44消息发送1)发送同步消息2)发送异步消息3)单向发送消息4)发送状态为sendStatus=SLAVE_NOT_AVAILABLE,但集群都好着呢,什么原因造成的有待考察,评论区的大神帮帮我~三. 消息消费1) 负载均衡模式(默认)2) 广播模式 ... -
Spring整合JMS异步消息
2017-11-03 12:00:22Spring整合JMS异步消息 在应用程序之间通信的消息,可分为同步消息和异步消息两种。前者就是当请求的程序端发出请求后,一直处于等待状态(阻塞),直到接收请求方反馈正确的结果后,请求方才能继续往下执行。而... -
基于异步消息模式的通信
2020-02-24 19:12:35基于异步消息模式的通信 使用消息机制时,微服务之间的通信采用异步交换消息的方式来完成。基于消息机制的应用程序通常使用消息代理,它充当服务之间的中介。 消息 消息由消息头部和消息主体组成。 头部包括:...