zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    git查看某个文件的提交记录
    git修改文件夹名字
    Visual Studio 2013 在使用 razor无智能提示的解决办法
    git部分提交
    SQL SERVER与C#的数据类型对应表
    使用VBS实现SSH远程登录并自动执行命令
    安装并配置Samba
    Trouble and solution
    两台电脑间共享文件
    Astah类图中使用list<>
  • 原文地址:https://www.cnblogs.com/549294286/p/5029530.html
Copyright © 2011-2022 走看看