开始看AMQConnection源码,这个也是一个比较大的类,首先我需要扫描相关的类,就是这个类相关成员变量,这篇主要解决HeartbeatSender, 看类名就知道是心跳发送类,具体看一下有什么方法和值得学习的地方
-
它是为一个AMQConnection管理和发送心跳检测,它线程独立于Connection工作线程,两者互不干扰
-
它是一个final类
1、 成员变量和常量
| 变量名和常量名 | 默认值 | 描述 |
|---|---|---|
| final Object monitor | new Object() | 同步锁对象 |
| final FrameHandler frameHandler | Frame处理器,详情参考源码分析 | |
| final ThreadFactory threadFactory | 线程工作类 | |
| ScheduledExecutorService executor | 周期执行(心跳任务) | |
| final boolean privateExecutor | 这个该类默认创建关闭时候也自动销毁,外部创建Executor不需要管 | |
| ScheduledFuture<?> future | 周期返回值 | |
| boolean shutdown | false | 标记是否关闭 |
| volatile long lastActivityTime | 最后一次活跃时间 |
- shutdown 成员变量为啥不加volatile关键字呢? 其实它在monitor锁下运行了,不存在多线程情况,而lastActivityTime是存在的
2、方法
| 方法名 | 描述 | 图示 |
|---|---|---|
| HeaderbeatSender(frameHandler, privateExecutor, executor, threadFactory) | 构造方法 | |
| void signalActivity() | 当前活动时间(发送Frame最近一次) | |
| void setHeartbeat(int heartbeatSeconds) | 设置心跳周期任务 | 1 |
| void shutdown() | 关闭操作 | 2 |
2.1、图示
- void setHeartbeat(int heartbeatSeconds)

- 总结
- 判断当前通道状态是关闭吗?如果关闭没有必要执行心跳任务了
- 判断future是否为空,也就说明原来是否有心跳任务在跑,有则需要取消历史任务
- 是否需要创建线程执行器,单个线程执行器
- 它是设置心跳一半触发发送心跳检测,本来60秒触发一次,现在就30秒触发一次, 防止最近活动时间在心跳后面,也就能够正常传输数据,也就说明心跳正常了,只有最近活动时间和心跳间隔一半 小于当前时间,说明需要发心跳检测了,且心跳检测是在0号通道上
- 执行周期任务心跳任务
- void shutdown()

- 总结
- 1.有一个疑问,为啥要做锁外关闭执行器呢,锁内为啥不行,难道执行shutdown可能导致死锁什么的?
3、总结
- 了解心跳定时周期任务
- 心跳默认通道是0
- 有个问题点就是为线程执行器需要到锁外执行关闭操作
本文解析AMQConnection中的HeartbeatSender类,探讨其构造、成员变量、方法及心跳周期管理,重点讲解了setHeartbeat方法的工作原理和shutdown操作的执行策略。

被折叠的 条评论
为什么被折叠?



