• 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 

  • 相关阅读:
    拍照上传图片方向调整
    js 压缩上传图片
    js 各种循环语法
    本地Git仓库对照多个远程仓库
    nrm安装与配置使用
    面试常见问题
    NodeJs文件路径
    vscode添加智能提示(typings)
    前端常用的工具库
    DeepMask学习笔记
  • 原文地址:https://www.cnblogs.com/zemliu/p/3928285.html
Copyright © 2020-2023  润新知