HashedWheelTimer
HashedWheelTimer 是根据
Hashed and Hierarchical Timing Wheels: Data Structures
for the Efficient Implementation of a Timer Facility
这篇论文做出来的.
HashedWheelTimer 主要用来高效处理大量定时任务, 他的原理如图

可以将 HashedWheelTimer 理解为一个 Set<Task>[] 数组, 图中每个槽位(slot)表示一个 Set<Task>
HashedWheelTimer 有两个重要参数
tickDuration: 每 tick 一次的时间间隔, 每 tick 一次就会到达下一个槽位
ticksPerWheel: 轮中的 slot 数
上图就是一个 ticksPerWheel = 8 的时间轮, 假如说 tickDuration = 100 ms, 则 800ms 可以走完一圈
在 timer.start() 以后, 便开始 tick, 每 tick 一次, timer 会将记录总的 tick 次数 ticks
我们加入一个新的超时任务时, 会根据超时的任务的超时时间与时间轮开始时间算出来它应该在的槽位.
例如 timer.newTask(new Task(10, TimeUnit.SECONDS));
表示加入一个 10s 后超时的任务, 那么, 先计算他应该在的槽位

// deadline = 当前时间 + 任务延迟 - timer启动时间 = timer启动到任务结束的时间
long deadline = System.currentTime() + timeout - timerStartTime; // calculated = tick 次数
long calculated = deadline / tickDuration;
// tick 目前已经 tick 过的次数
final long ticks = Math.max(calculated, tick); // Ensure we don't schedule for past.
// 算出任务应该插入的 wheel 的 slot, slotIndex = tick 次数 & mask, mask = wheel.length - 1, 默认即为 511
stopIndex = (int) (ticks & mask);
// 计算剩余的轮数, 只有 timer 走够轮数, 并且到达了 task 所在的 slot, task 才会过期
remainingRounds = (calculated - tick) / wheel.length;

其中 stopIndex 为它所在的槽位
remainingRounds 为它从 timer 启动时应该经过的轮数
当 timer tick 到 task 所在的槽位, 并且这个槽位的 remainingRounds <= 0 , 则说明这个 task 超时, 然后执行超时任务, 否则 remainingRounds--
------------------------------------------------------
为什么要使用时间轮的环形结构? 因为环形结构可以根据超时时间的 hash 值(这个 hash 值实际上就是ticks & mask)将 task 分布到不同的槽位中, 当 tick 到那个槽位时, 只需要遍历那个槽位的 task 即可知道哪些任务会超时(而使用线性结构, 你每次 tick 都需要遍历所有 task), 所以, 我们任务量大的时候, 相应的增加 wheel 的 ticksPerWheel 值, 可以减少 tick 时遍历任务的个数.
详细代码参考 Netty 的实现:https://github.com/netty/netty/blob/master/common/src/main/java/io/netty/util/HashedWheelTimer.java
HashedWheelTimer的更多相关文章
- HashedWheelTimer 原理
HashedWheelTimer 是根据 Hashed and Hierarchical Timing Wheels: Data Structuresfor the Efficient Impleme ...
- netty定时器HashedWheelTimer(zz)
http://www.tianjiaguo.com/programming-language/java-language/netty%E5%AE%9A%E6%97%B6%E5%99%A8hashedw ...
- Netty 工具类 —— HashedWheelTimer 讲解
一.前言 首先有一篇超时任务的实战分析,文章简短精炼明了,阐述了,为什么要用HashedWheelTimer. https://chuansongme.com/n/1650380646616 看完后, ...
- 使用netty HashedWheelTimer构建简单延迟队列
背景 最近项目中有个业务,需要对用户新增任务到期后进行业务处理.使用定时任务定时扫描过期时间,浪费资源,且不实时.只能使用延时队列处理. DelayQueue 第一想到的是java自带的延时队列del ...
- Netty源码解析 -- FastThreadLocal与HashedWheelTimer
Netty源码分析系列文章已接近尾声,本文再来分析Netty中两个常见组件:FastThreadLoca与HashedWheelTimer. 源码分析基于Netty 4.1.52 FastThread ...
- Rust 实现Netty HashedWheelTimer时间轮
目录 一.背景 二.延迟队列-时间轮 三.Netty 时间轮源码分析 四.Rust实现HashedWheelTimer 五.总结思考 一.背景 近期在内网上看到一篇文章,文中提到的场景是 系统自动取消 ...
- netty系列之:HashedWheelTimer一种定时器的高效实现
目录 简介 java.util.Timer java.util.concurrent.ScheduledThreadPoolExecutor HashedWheelTimer 总结 简介 定时器是一种 ...
- LinkedIn的即时消息:在一台机器上支持几十万条长连接
最近我们介绍了LinkedIn的即时通信,最后提到了分型指标和读回复.为了实现这些功能,我们需要有办法通过长连接来把数据从服务器端推送到手机或网页客户端,而不是许多当代应用所采取的标准的请求-响应模式 ...
- netty研究【1】:编译源代码
netty作为异步通信底层框架,其优异的性能让我产生了研究他的源码的决定. 代码研究之前,第一步就是要准备环境,至少可以编译通过,下面,就拿github上的4.1分支进行.我的IDE是Intellij ...
随机推荐
- System.Data.OracleClient.OracleConnection已过时
解决办法如下: 1.把原来的using System.Data.OracleClient;去掉 2.在oracle安装目录下找到Oracle.DataAccess.dll 添加引用:using Ora ...
- WCF Basic Concept
http://msdn.microsoft.com/library/ee354180.aspx Steps: Designing a Service Contract Implementing a W ...
- MySQL 5.6.3
SHOW VARIABLES LIKE '%version%'; https://dev.mysql.com/doc/refman/5.6/en/explain.html As of MySQL 5. ...
- windows系统中ubuntu虚拟机安装及web项目到服务上(二)
ajp方式整合apache2和tomcat 7 1:在apache2.conf配置文件中启用模块mod_proxy_ajp,在里面添加 LoadModule proxy_module modules/ ...
- 用户控件UserControl图片资源定位(一)---Xaml引用图片
MEF编程实现巧妙灵活松耦合组件化编程,一些细节需要花费不小心思去处理: 其中组件中若包含用户控件,且需要访问图片资源,那么Xaml引用资源需要做以下设置 1. 用户控件(usercontrol)所在 ...
- 安装CentOS Core之后布置环境脚本
#启动ssh服务 service sshd start #安装vim编辑器 echo y | yum install vim #安装网络工具包 echo y | yum install net-too ...
- 配置 android环境
1.如上图,下载最新adt-bundle: http://developer.android.com/sdk/index.html 里面集成了 eclipse,SDK,SDK Manager. 2 ...
- swift-03-构造器(Designated&&Convenience)
类里面所有的存储型属性--包括所有继承自父类的属性,都必须在构造过程中设置初始值. 构造器,为了确保所有类实例中的存储型属性都能获得初始值,设置了两个构造器--他们分别是指定构造器和便利构造器. ...
- sell-- 英文网站产品显示404?
1. 简介: 通过在主页(header.jsp)查询B22212,在localhost本地, cn和us查询的结果search.jsp中显示都是没有找到! 但是在外网(www),cn能够查询到,并展示 ...
- iOS:crash崩溃日志分析
一.前言: 作为一个合格的iOS开发者,除了具有规范强悍的编码能力外,还应该具有过硬的查错纠错能力.在项目运行时,程序崩溃是不可避免的,遇到这个问题,有时会出现一大堆的crash日志,艹,貌似看不懂呀 ...