定时任务之时间轮算法

news2024/10/7 6:45:53

初识时间轮

我们先来考虑一个简单的情况,目前有三个任务A、B、C,分别需要在3点钟,4点钟和9点钟执行,可以把时间想象成一个钟表。

如上图中所示,我只需要把任务放到它需要被执行的时刻,然后等着时针转到这个时刻时,取出该时刻放置的任务,执行就可以了。 这就是时间轮算法最核心的思想了。 时针怎么转呢? while-true-sleep ,也可以使用空的阻塞队列加上超时时间进行睡眠。

在大多数情况中同一时刻可能需要执行多个任务,比如每天上午九点除了生成报表之外,还需要执行发送邮件的任务,需要执行创建文件的任务等等。

时间轮的数据结构。首先,时间轮的刻度可以用数组或者链表表示,每个刻度就是一个槽,槽用来存放该刻度需要执行的任务,如果有多个任务需要执行呢?每个槽里面放一个链表就可以了,就像下面图中这样:

同一时刻存在多个任务时,只要把该刻度对应的链表全部遍历一遍,执行(扔到线程池中异步执行)其中的任务即可。

简单时间轮的实现

由一个 hash table和链表实现,HashTable 的 key 值为时间单位,value 为链表的 root 节点。

时间刻度不够用怎么办?

上述时间轮表示一天的时间,但如果任务不只限定在一天之内呢?比如我有个任务,需要每周一上午1点执行,我还有另一个任务,需要每月的第十二天的上午四点执行。一种很容易想到的解决办法是:

1.增大时间轮的刻度

一天24个小时,一周168个小时,一月720个小时,为了解决上面的问题,我可以把时间轮的刻度(槽)从12个增加到168个,所以每周一上午1点就是时间轮的第1个刻度,每周五上午4点就是时间轮的第100个刻度,示意图如下:

仔细思考一下,会发现这种方式存在几个缺陷:

1.时间刻度太多会导致时间轮走到的多数刻度没有任务执行,比如一个月就2个任务,按照一个月30天算,需要移动720次,其中718次是无用的。

2.时间刻度太多会导致存储空间变大,利用率变低。

这种方式直接导致空间复杂度变大。

2.增加圈数

为每个任务增加一个圈数round标识,每次遍历到这个任务时,圈数减1,当圈数为0时,执行该任务,示意图如下:

但这种,每次时间轮转动,都需要对整个任务链表进行计算,增加了时间复杂度。最完美的实现就是转到对应刻度时,执行该刻度下所有的任务。

分层时间轮

分层时间轮是这样一种思想:每个时间粒度对应一个时间轮,多个时间轮之间进行级联协作。基于这个思想,我们可以设置三个时间轮:月轮、周轮、天轮。

比如有一个任务三每个月12号上午九点。

月轮的刻度为30天,周轮的刻度为7天,天轮为24小时。

这个任务需要月轮的时间刻度转动到12号这一天,然后才需要关注其更细一级的时间单位:上午9点。

初始添加任务时,任务一每周二上午九点,任务二每周四上午九点,任务三每个月12号上午九点。为任务一添加到天轮上,任务二添加到周轮上,任务三添加到月轮上。三个时间轮以各自的时间刻度不停流转。

当周轮移动到刻度2(星期四)时,取出这个刻度下的任务,丢到天轮上,天轮接管该任务,到9点执行。

同理,当月轮移动到刻度12(12号)时,取出这个刻度下的任务,丢到天轮上,天轮接管该任务,到9点执行。

这样就可以做到既不浪费空间,有不浪费时间。

整体的示意图如下所示:

定时器一览

1.无序定时器列表

2.有序定时器列表

3. 定时器树

4. 简单的计时轮

5. 带有有序定时器列表的哈希轮

6. 带有无序定时器列表的哈希轮

7.分层时间轮

时间轮的应用

时间轮的思想应用范围非常广泛,各种操作系统的定时任务调度,Redisson、Crontab、Netty、Kafka、Caffeine等组件的时间任务调度均采用时间轮的思想。

在不同的场景下,选择合适的定时器。

参考资料

hashed-and-hierarchical-timeing-wheels论文:Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility | the morning paper

时间轮简介:时间轮timewheel算法_天涯泪小武的博客-CSDN博客

netty时间轮分析:Netty时间轮 - 腾讯云开发者社区-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IP协议(网络层重点协议)

目录 一、IP协议报头格式 二、地址选择 1、IP地址 (1)格式 (2)组成 (3)分类 (4)子网掩码 三、路由选择 IP协议是网络层的协议,它主要完成两个方面的任务&#xf…

4.16--设计模式之创建型之代理模式(总复习版本)---脚踏实地,一步一个脚印

1.代理对象 定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,从而实现对真实对象的操作。 通俗的来讲代理模式就是我们生活中常见的中介。 在代理模式中,代理对象主要起到一个中介的作用,…

初识Docker并在linux完成安装

文章目录一、 初识Docker1.1 简介1.2 Docker和虚拟机的异同1.3 Docker架构二、 DockerHub三、Docker的安装一、 初识Docker 1.1 简介 Docker是一种开源的容器化平台,可以让开发者在容器中打包、发布、运行和管理应用程序。它使用轻量级的容器来隔离应用程序和它们的…

Scrapy爬虫基本使用与股票数据Scrapy爬虫

Scrapy爬虫的常用命令 scrapy命令行格式 红色是常用的三种命令 为什么Scrapy采用命令行创建和运行爬虫? 命令行(不是图形界面)更容易自动化,适合脚本控制 本质上,Scrapy是给程序员用的,功能&#xff08…

vue打包之后,可以进行修改配置后端地址、端口等信息方法

前言 用vue-cli构建的项目通常是采用前后端分离的开发模式,也就是前端与后台完全分离,此时就需要将后台接口地址打包进项目中,但是,难道我们只是改个接口地址也要重新打包吗?当然不行了,那就太麻烦了&#…

支付宝沙箱环境+SpringBoot+内网穿透整合开发

目录 1.查看沙箱账号 2.内网穿透 3.沙箱环境整合SpringBoot开发 下面我将以实际案例详细介绍如何使用沙箱环境进行支付宝支付对接的开发 1.查看沙箱账号 首先什么是沙箱账号? 沙箱账号是指在支付宝沙箱环境中创建的测试账户,用于模拟真实的支付流程…

The 2022 ICPC Asia Xian Regional Contest

题目顺序大致按照难度排序。 F. Hotel 现在酒店中有单人间和双人间,价格分别是c1,c2,现在有n个队,每队三个人,性别分别用字母表示,当两个人性别相同且在同一个队时,他们可以住在双人间中。求最…

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo写在前面环境配置创建虚拟环境安装库项目运行写在前面 相信很多朋友跟我一样在github等平台上偷代码 (读书人的事怎么能叫偷呢) 的时候会发现伟大且无私的作者虽然开源了代码但是readme文件该写的没写&#x…

2023TYUT移动应用软件开发程序设计和填空

目录 程序设计 程序设计1:根据要求设计UI,补充相应布局文件,即.xml文件 程序设计2:根据要求,补充Activity.java文件 程序填空 说明: 程序设计 程序设计1:根据要求设计UI,补充相应布局文件,即.xml文件…

【C++初阶】第十篇:list模拟实现

文章目录一、list的模拟实现三个类及其成员函数接口总览结点类的模拟实现迭代器类的模拟实现迭代器类的模板参数说明迭代器operator->的重载迭代器模拟实现代码list的模拟实现无参构造函数带参构造拷贝构造函数赋值运算符重载函数析构函数begin和endinserteraselist的迭代器…

WordPress添加阿里云OSS对象云储存配置教程

背景:随着页面文章增多,内置图片存储拖连网站响应速度,这里对我来说主要是想提升速度 目的:使用第三方云存储作为图片外存储(图床),这样处理可以为服务器节省很多磁盘空间,在网站搬家的时候减少文件迁移的工…

【数据结构】堆(笔记总结)

👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:数据结构 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&…

MySQL--数据库基础--0406

目录 1.什么是数据库? 2. 基本使用 2.1 连接服务器 2.2 数据库的操作在Linux中的体现 2.3 使用案例 3.服务器,数据库,表关系 4.数据逻辑存储 5.SQL的分类 6.存储引擎 1.什么是数据库? 数据库和文件 文件或者数据库&…

OK-MX93开发板-实现Web页面无线点灯

上篇文章:i.MX9352——介绍一款多核异构开发板,介绍了OK-MX9352开发板的基础硬件功能。 本篇来使用OK-MX9352开发板,通过Web界面进行点灯测试,最终的效果如下: 在进行代码编写之前,先在Ubuntu虚拟机上把这…

对比损失Contrastive Loss(CVPR 2006)原理解析

paper:http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf 本文提出的对比损失contrastive loss被广泛应用于自监督模型中,但最初对比损失是作为一个特征降维方法而提出的。 摘要 降维是学习一种映射关系,通过这种映射关…

day10 线程池及gdb调试多线程

目录 线程池的概念 概念: 必要性: 线程池的基本结构: 线程池的实现 完整代码 线程的GDB调试 线程池的概念 概念: 通俗的讲就是一个线程的池子,可以循环的完成任务的一组线程集合; 必要性&#xff…

【软件工程】为什么要选择软件工程专业?

个人主页:【😊个人主页】 文章目录前言软件工程💻💻💻就业岗位👨‍💻👨‍💻👨‍💻就业前景🛩️🛩️🛩️工作环…

趣谈之什么是 API 货币化?

本文介绍了 API 货币化和 APISIX 实现 API 货币化方法。 作者刘维,API7.ai 技术工程师,Apache APISIX Contributor 原文链接 什么是 API 货币化 想象你开发并部署了一个服务,能够搜集你所在城市所有超市的打折和优惠信息,其他的…

C生万物 | 校招热门考点 —— 结构体内存对齐

文章目录一、前言结构体偏移量计算:offsetof二、规则介绍例题的分解与细说三、习题演练1、练习①2、练习②四、为什么存在内存对齐?1、平台原因(移植原因)2、性能原因五、如何修改默认对齐数六、实战演练✍一道百度笔试题: offsetof 宏的实现&#x1f4…

深度学习基础篇之深度神经网络(DNN)

神经网络不应该看做是一个算法,应该看做是一个特征挖掘方法。在实际的业界发展过程中,数据的作用往往大于模型,当我们把数据的隐藏特征提取出来之后,用很简单的模型也能预测的很好。 神经网络模型由生物神经中得到启发。在生物神…