时间轮算法HashedWheelTimer

article/2025/7/28 1:16:24

文章目录

    • 一.HashedWheelTimer是什么?
    • 二.能干什么?为什么需要这个东西?
      • 优点
      • 适用场景
    • 三.怎么用?使用步骤
      • 1.引入pom
      • 2.使用举例
    • 四.时间轮原理
    • 五.使用注意点
      • 1.一个HashedWheelTimer对象只有一个worker线程
      • 2.每次添加的任务只会执行一次
      • 3.时间轮的参数非常重要
      • 4.所有的任务都是顺序串行执行的

一.HashedWheelTimer是什么?

   时间轮是一种非常惊艳的数据结构。其在Linux内核中使用广泛,是Linux内核定时器的实现方法和基础之一。
   换句话说时间轮是一种高效来利用线程资源来进行批量化调度的一种调度模型。把大批量的调度任务全部都绑定到同一个的调度器上面,使用这一个调度器来进行所有任务的管理(manager),触发(trigger)以及运行(runnable)。能够高效的管理各种延时任务,周期任务,通知任务等等
   而HashedWheelTimer则是使用了时间轮这种数据结构,它是Netty内部的一个工具类,最开始主要用来优化I/O超时的检测,本文将详细分析HashedWheelTimer的使用及原理。

二.能干什么?为什么需要这个东西?

优点

      其实笔者认为其最大的优点就是可以在一个线程中动态的添加定时(延时)任务
像我们经常使用Timer,ScheduledExecutorService,Spring的Scheduled这些都是无法做到这一点的,一旦某个线程开始执行某个定时任务,都是无法再去动态添加的

      那某些场景,比如说有很多小的定时任务,难道每一个都去起一个线程处理吗?那数量多的话对程序势必影响很大,浪费资源,这个时候就可以考虑HashedWheelTimer了.

      而在netty中,因为其可能管理上百万的连接,每一个连接都会有很多超时任务。比如发送超时、心跳检测间隔等,如果每一个定时任务都启动一个Timer,不仅低效,而且会消耗大量的资源。所以创造了这个工具类.

适用场景

  1. 订单超时
  2. 分布式锁中为线程续期的看门狗
  3. 心跳检测

三.怎么用?使用步骤

1.引入pom

<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.45.Final</version>
</dependency>

2.使用举例

1.构建对象,添加定时任务

        //在一个格子里面的并不会区分的很细,而会依次顺序执行,所以适用于对时间精度要求不高的任务//构建时间轮对象HashedWheelTimer timer = new HashedWheelTimer(5, TimeUnit.SECONDS, 10);//添加定时任务1,延迟2s执行timer.newTimeout((TimerTask) timeout -> {System.out.println("任务1执行");System.out.println("线程名称:"+Thread.currentThread().getName());},2,TimeUnit.SECONDS);//添加定时任务2,延迟2s执行timer.newTimeout((TimerTask) timeout -> {System.out.println("任务2执行");System.out.println("线程名称:"+Thread.currentThread().getName());},5,TimeUnit.SECONDS);//等待定时任务执行完毕后,将时间轮内部工作线程停止,这里只是粗略的等待,也可以使用CountDownLatchThread.sleep(10000);timer.stop();

2.取消某个定时任务

       //构建时间轮对象HashedWheelTimer timer = new HashedWheelTimer(1, TimeUnit.SECONDS, 10);//添加定时任务1Timeout newTimeout = timer.newTimeout((TimerTask) timeout -> {System.out.println("任务1执行");System.out.println("线程名称:" + Thread.currentThread().getName());}, 5, TimeUnit.SECONDS);//现在又想取消掉这个任务if(!newTimeout.isExpired()){newTimeout.cancel();}

四.时间轮原理

   时间轮其实就是一种环形的数据结构,可以想象成时钟,分成很多格子,一个格子代码一段时间(这个时间越短,Timer的精度越高)。并用一个链表表示在该格子上的到期任务,同时一个指针随着时间一格一格转动,并执行相应格子中的到期任务。任务通过取摸决定放入那个格子。如下图所示:
在这里插入图片描述

   假设一个格子是1秒,则整个wheel能表示的时间段为8s,假如当前指针指向2,此时需要调度一个3s后执行的任务,显然应该加入到(2+3=5)的方格中,指针再走3次就可以执行了;如果任务要在10s后执行,应该等指针走完一个round零2格再执行,因此应放入4,同时将round(1)保存到任务中。检查到期任务时应当只执行round为0的,格子上其他任务的round应减1。

再回头看看构造方法的三个参数分别代表

  • tickDuration
    每一tick的时间
  • timeUnit
    tickDuration的时间单位
  • ticksPerWheel
    就是轮子一共有多个格子,即要多少个tick才能走完这个wheel一圈。

五.使用注意点

1.一个HashedWheelTimer对象只有一个worker线程

2.每次添加的任务只会执行一次

3.时间轮的参数非常重要

   比如我这里设置每个格子的时间为6s,添加了两个定时任务,一个延时2s执行,一个延时5s执行,但是最终执行结果是同时执行,因为这两个任务都被分配到第一个格子中,按顺序执行.
   所以时间轮的参数要根据时间情况具体设定

在这里插入图片描述

4.所有的任务都是顺序串行执行的

也就是说上一个任务的异常延时会影响到下一个任务.
比如我这里添加了两个定时任务,第一个延时2s,第二个延时5s,但是因为第一个任务的延时,导致第二个延时了10s才执行.
在这里插入图片描述
所以这里要求时间轮执行的任务都是比较快的, 或者这里可以使用异步任务去处理.

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述


http://chatgpt.dhexx.cn/article/uB96GTZY.shtml

相关文章

时间轮-理论篇

1. 引言 定时任务再开发过程中无处不在&#xff0c;定时发送消息&#xff0c;定时更新数据库表的状态&#xff0c;Linux系统定时执行脚本等等。这些操作都离不开定时任务&#xff0c;那么这些定时任务是怎么实现的是否又去想过。如果让开发者自己去实现一个定时任务又该怎么实…

定时任务的实现原理:时间轮算法

文章目录 前言时间轮定时使用方式时间轮定时内部原理时间轮定时源码剖析构造方法添加任务工作线程启动工作线程run方法指针跳动将队列任务放入时间轮中链表任务遍历定时任务执行 前言 最近在思考实现定时任务的几种方式&#xff0c;比如 quartz&#xff0c;delay queue&#xf…

时间轮-Java实现篇

在前面的文章《时间轮-理论篇》讲了时间轮的一些理论知识&#xff0c;然后根据理论知识。我们自己来实现一个简单的时间轮。 1. 理论抽象 将时间轮的理论进行抽象&#xff0c;主要有两个方面&#xff1a; 时间轮的转动每一个时间间隔任务的处理&#xff0c;从时间间隔的Buke…

时间轮timewheel算法

时间轮是个不太常见&#xff0c;但在部分场景有较高使用价值的工具。 时间轮常用于延时任务&#xff0c;在Netty、akka、Quartz、Zookeeper等高性能组件中都存在时间轮定时器的踪影。 从定时任务说起 自然界中定时任务无处不在&#xff0c;太阳每天东升西落&#xff0c;候鸟的…

定时器实现原理——时间轮

时间轮 时间轮算法是通过一个时间轮去维护定时任务&#xff0c;按照一定的时间单位对时间轮进行划分刻度。然后根据任务延时计算任务落在该时间轮的第几个刻度上&#xff0c;如果任务时长超出了刻度数量&#xff0c;则需要增加一个参数记录时间轮需要转动的圈数。 简单时间轮…

时间轮算法

一、时间轮算法 1. 时间轮的基本概念 Kafka中存在大量的延时操作&#xff0c;如延时生产、延时消费等&#xff1b;而JDK中自带的 Timer 和 DelayQueue 的插入和删除操作的平均复杂度为 O&#xff08;nlogn&#xff09;&#xff0c;无法满足 Kafka 的高性能要求&#xff0c;因…

时间轮算法(TimingWheel)

时间轮算法的应用非常广泛&#xff0c;在 Dubbo、Netty、Kafka、ZooKeeper、Quartz 的组件中都有时间轮思想的应用&#xff0c;甚至在 Linux 内核中都有用到。 其思想理论基础可以参考论文&#xff1a;http://www.cs.columbia.edu/~nahum/w6998/papers/ton97-timing-wheels.pd…

那些惊艳的算法们(三)—— 时间轮

从定时任务说起 自然界中定时任务无处不在&#xff0c;太阳每天东升西落&#xff0c;候鸟的迁徙&#xff0c;树木的年轮&#xff0c;人们每天按时上班&#xff0c;每个月按时发工资、交房租&#xff0c;四季轮换&#xff0c;潮涨潮落&#xff0c;等等&#xff0c;从某种意义上…

1、时间轮

一、什么是时间轮&#xff1f; 作为一个粗人&#xff0c;咱不扯什么高级的词汇&#xff0c;直接上图&#xff1a; 上面是一张时间轮的示意图&#xff0c;可以看到&#xff0c;这个时间轮就像一个钟表一样&#xff0c;它有刻度&#xff0c;图中画了9个格子&#xff0c;每个格子…

浅谈时间轮算法

浅谈时间轮算法 基于队列的定时任务执行模型缺陷 在计算机世界中&#xff0c;只有待解决的问题变得大规模后&#xff0c;算法的价值才能够最大化的体现。时间轮算法可以将插入和删除操作的时间复杂度都降为 O(1)&#xff0c;在大规模问题下还能够达到非常好的运行效果。 如果…

时间轮(TimingWheel)算法总结

通过阅读篇文章您可以很容易理解平时所使用的开源框架是如何进行任务调度的。而且对于以后业务上碰到需要做时间任务调度的需求&#xff0c;也可以尝试着用实践论算法去实现。 一、时间轮的应用 其实早在1987年&#xff0c;时间轮算法的论文已经发布。论文名称&#xff1a;Hash…

时间轮 (史上最全)

缓存之王 Caffeine 中&#xff0c;涉及到100w级、1000W级、甚至亿级元素的过期问题&#xff0c;如何进行高性能的定时调度&#xff0c;是一个难题。 注&#xff1a; 本文从 对 海量调度任务场景中&#xff0c; 高性能的时间轮算法&#xff0c; 做了一个 系统化、由浅入深的 穿透…

时间轮(Timing Wheel)案例和原理

什么是时间轮(Timing Wheel) 时间轮(Timing Wheel)是George Varghese和Tony Lauck在1996年的论文Hashed and Hierarchical Timing Wheels: data structures to efficiently implement a timer facility实现的&#xff0c;它在Linux内核中使用广泛&#xff0c;是Linux内核定时器…

时间轮(TimingWheel)

一、什么是时间轮 时间轮其实就是一种环形的数据结构&#xff0c;可以想象成时钟&#xff0c;分成很多格子&#xff0c;一个格子代表一段时间&#xff08;这个时间越短&#xff0c;Timer的精度越高&#xff09;。并用一个双向链表存储放在该格子上的延时任务&#xff0c;同时一…

高性能定时器3——时间轮

​ 在网络程序中我们通常要处理三种事件&#xff0c;网络I/O事件、信号以及定时事件&#xff0c;我们可以使用I/O复用系统调用&#xff08;select、poll、epoll&#xff09;将这三类事件进行统一处理。我们通常使用定时器来检测一个客户端的活动状态&#xff0c;服务器程序通常…

C#,斐波那契数列(Fibonacci Sequence)的八种算法与源代码

一、莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09; 斐波那契公元1170年生于意大利比萨&#xff0c;卒于1250年&#xff0c;被人称作“比萨的莱昂纳多”&#xff0c;是一名闻名于欧洲的数学家&#xff0c;其主要的著作有《算盘书》、《实用几何》和《四艺经》等。…

matlab斐波那契数列画图,斐波拉契数列 斐波那契数列 matlab程序

斐波那契数列数列从第3项开始,每一项都等于前两项之和。 例子:数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368 应用: 生活斐波那契 斐波那契数列中的斐波脾气有点大,表面温和到别人误以为很好欺…

快速计算斐波那契数列(Fibonacci数列)

本文最后更新于 619 天前&#xff0c;其中的信息可能已经有所发展或是发生改变。 题目描述 输入一个正整数n&#xff0c;求Fibonacci数列的第n个数。Fibonacci数列的特点&#xff1a;第1,2个数为1,1。从第3个数开始&#xff0c;概述是前面两个数之和。即&#xff1a; 要求输入的…

递归求斐波那契数列

斐波那契数列 题目描述&#xff1a;编写一个函数&#xff0c;求斐波那契数列的第n项的值。 首先&#xff0c;对于斐波那契数列&#xff0c;我们是非常熟悉了&#xff0c;对斐波那契定义为如下&#xff1a;f(0)0,f(1)0,f(2)1,……f(n)f(n-1)f(n-2)&#xff0c;其中n>1。对于这…

斐波那契数列(Fibonacci)

有一对兔子&#xff0c;出生后第3个月起每个月都生一对免子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死&#xff0c;问40个月的免子总数为多少?解题思路&#xff1a; 这是一个有趣的古典数学问题。可以从表1看出兔子繁殖的规律。 …