(一)MessageQueue之消息入队
时间:2022-07-23
本文章向大家介绍(一)MessageQueue之消息入队,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
java 尾插法插入单链表
每来一个新节点,插入到链表的最后
先用伪代码整理一下思路,如下:
public class SimpleNode {
// 当前链表,
Node mNode;
public void insert(Node node) {
// 1.链表为null,第一次插入
if (mNode == null) {
//node作为第一个元素,放入mNode
} else {
//2.1 链表不为null,找出最后一个节点
//2.2 将待插入节点 Node 插入 最后一个节点之后
}
}
//节点
public class Node {
int data;
Node next;
public Node() {
this.next = null;
}
}
}
因此我们的代码可以这么写:
public class SimpleNode {
// 当前链表
Node mNode;
public class Node {
int data;
Node next;
public Node() {
this.next = null;
}
}
public void insert(Node node) {
//创建一个临时节点
Node currentNode = mNode;
// 1.链表为null,第一次插入
if (currentNode == null) {
mNode = node;
} else {
// 2.1 遍历链表,找出最后一个节点
Node realLastNode;
for (; ; ) {
realLastNode = currentNode;
currentNode = currentNode.next;
//在 for 循环中,如果此时currentNode为 null,说明链表没有节点了,即realLastNode.next为 null,
//realLastNode就是我们要找的节点,退出 for 循环
if (currentNode == null) {
break;
}
}
//将待插入节点 Node 插入到最后
realLastNode.next = node;
}
}
}
MessageQueue 中的 msg 入队
有了上面的知识,我们看一下MessageQueue 是怎么将 msg 入队的?
按照我个人的理解,有如下几点:
- 在MessageQueue中msg按照时间顺序进入消息队列
- 延迟越大的消息,越在队列的后面
假设发送消息的时间单位为秒
假设消息只入队,不消费.
比如我们在 16:10:40s 入队一个消息 A,41s入队的消息 B,42s 入队消息C
则 BC都在 A 的后面,
因此在MessageQueue中 msg按时间顺序排队
顺序是 ABC
源码分析
public final class MessageQueue {
boolean enqueueMessage(Message msg, long when) {
//...
//同步方法块
synchronized (this) {
//...
msg.when = when;
Message p = mMessages;
boolean needWake;
//1.1 当前mMessages 为 null,队列中没有消息
//1.2 当前mMessages 不为 null,when == 0说明队列中的消息都是延迟的消息
//1.3 当前mMessages 不为 null,when < p.when 说明当前消息是延迟消息,但是队列中的消息比我这个消息延迟还大.
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
//将当前消息作为mMessages的第一个
//此时 p 是 null
msg.next = p;
//更新mMessages
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;
}
}
//此时 p 是 null
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
}
代码中的注释,就是消息入队的过程
更多内容 欢迎关注公众号
- 学习利用JSON 摆脱表单与业务对象双向转换的繁琐工作
- 代码也疯狂:diagram生成流程图
- 设置你的Gravatar头像的方法
- 阅读Ext 学习Javascript(二)Core/Ext.extend 从继承说起
- IronPython资料
- WordPress免插件仅代码实现“返回顶部、返回底部、评论”效果(样式一)
- encodeURIcomponent编码和ASP.NET之间编码转换
- WordPress免插件仅修改代码去掉评论/留言里的链接
- 阅读Ext 学习Javascript(一)Core/Ext.js
- 利用腾讯的ip地址库做ip地址定位
- WordPress登陆不了后台的原因及解决方法(登陆界面不断返回)
- select元素的options.add 与 insertbefore的区别
- 如何去理解 拓扑排序算法
- WordPress免插件仅代码实现文章归档(模板页面)I
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 实操 | kafka如何手动异步提交offset
- 解惑 | 为什么我根据时间戳获得的offset为空呢?
- spring-boot使用aop进行日志记录
- openGauss备机追数Catchup过程中主库写入阻塞问题
- openGauss830版本中对于备份模块的增强与当前问题
- spring boot自动配置原理
- 网站日志分析完整实践
- 聊聊分布式下的WebSocket解决方案
- pod安装、更新库失败,github连接超时问题
- Mysql如何给字符串添加索引(前缀索引)
- Python中5对必知的魔法方法
- java的三种代理
- 不写爬虫,也能读取网页的表格数据
- ReentrantLock的公平与非公平
- JVM 类加载机制详解