您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > .NET

.Net 之时间轮算法(终极版)

时间:2022-07-05 16:50:56  来源:  作者:交流科技圈

关于时间轮算法的起始

我也认真的看了时间轮算法相关,大致都是如下的一个图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述 个人认为的问题

大部分文章在解释这个为何用时间轮的时候都再说

 

为什么要用时间轮实现

  1. 1. 通常用于实现linux内核任务、游戏类的buf计时。
  2. 2. 单个时间轮局限性:保存的任务数量少,不能超过当前时间轮。
  3. 3. 多层时间轮,典型:日-时-分-秒
  4. 4. 传统JAVA实现定时:Timer,只能单线程,会阻塞;Executors.newScheduledThreadPoll, 使用的最小堆来实现,任务还是不能太多,添加时间复杂度为O(logn)

时间轮定时器最大的优点

  1. 1. 是任务的添加与移除,都是O(1)级的复杂度;
  2. 2. 不会占用大量的资源;
  3. 3. 只需要有一个线程去推进时间轮就可以工作了
 
privateTask[很长] tasks;

publicList<Task> getTaskList( longtimestamp) {

returntask. get(timestamp)

}

// 假装这里真的能一毫秒一个循环

publicvoidrun{

while( true){

getTaskList(System.currentTimeMillis).后台执行

Thread.sleep( 1);

}

}

假如这个数组长度达到了亿亿级,我们确实可以这么干。那如果将精度缩减到秒级呢?我们也需要一个百亿级长度的数组。

先不说内存够不够,显然你的定时器要这么大的内存显然很浪费。

基于个人的理解对其进行改造和实现

对于以上的描述,我自己还是很不认同的,我为啥要声明这么大的数组,难道不能有一个任务,我就放一个任务么,实际数组的长度应该是你任务数的长度吧。

要不然,为啥要这么浪费。想不通,可能还有别的解释,谁有答案可以告诉我。

在实际的使用中,一般都为秒级,毫秒级都很少,因为毫秒级的不准。

所以,我可以根据这些通过hash字典构建一个 这样的时间轮算法,也作为我自己想实现定时任务框架的一部分。

逻辑:核心为一个字典,key 为时间戳,值为任务列表。整体就是每个添加的任务都有一个触发的时间(秒),到了这个秒,时间就会触发,自然会去执行相关的任务。有了任务才会添加,不会任何任务都添加的。任务触发的时候,会获取任务下一次执行的时间,并插入到任务列表里。

static void MAIn( string[] args)

{

ScheduledTask scheduledTask = newScheduledTask( => { Console.WriteLine( $" {DateTime.Now}" ); }, newTimeSpan( 0, 0, 5));

TimeWheel timeWheel = newTimeWheel;

timeWheel.AddTask(scheduledTask);

timeWheel.Run;

Console.WriteLine( "开始运行时间轮!");

Console.ReadLine;

} ///<summary>

///时间轮算法(终极)实现

///大部分都是支持秒级,所以,按照秒级进行实现

///</summary>

publicclassTimeWheel

{

///<summary>

///任务列表

///</summary>

publicConcurrentDictionary< long, List<IScheduledTask>> Tasks = new;

publicvoidRun

{

while( true)

{

varnow = DateTime.Now;

Task.Run( => { Trigger(now); });

varoffset = 500- now.Millisecond;

SpinWait.SpinUntil( => false, 1000+ offset);

}

}

publicvoidTrigger(DateTime dateTime)

{

vartimeStamp = GenerateTimestamp(dateTime);

varoldTimeStamp = timeStamp - 1;

Tasks.TryRemove(oldTimeStamp, outvar_);

Tasks.TryGetValue(timeStamp, outvarresult);

if(result?.Any == true)

{

foreach( varitem inresult)

{

Task.Run(item.GetAction);

varNewTime = item.GetNextTime;

if(NewTime.HasValue)

{

AddTask(NewTime.Value, item);

}

}

}

}

publicvoidAddTask(IScheduledTask scheduledTask)

{

vartimeStamp = GenerateTimestamp(scheduledTask.GetNextTime.Value);

Tasks.AddOrUpdate(timeStamp, newList<IScheduledTask> { scheduledTask }, (k, v) =>

{

v.Add(scheduledTask);

returnv;

});

}

publicvoidAddTask(DateTime dateTime, IScheduledTask scheduledTask)

{

vartimeStamp = GenerateTimestamp(dateTime);

Tasks.AddOrUpdate(timeStamp, newList<IScheduledTask> { scheduledTask }, (k, v) =>

{

v.Add(scheduledTask);

returnv;

});

}

privatelongGenerateTimestamp(DateTime dateTime)

{

returnnewDateTimeOffset(dateTime.ToUniversalTime).ToUnixTimeSeconds;

}

privateDateTime GetDatetime( longtimeStamp)

{

vard = DateTimeOffset.FromUnixTimeSeconds(timeStamp);

returnd.LocalDateTime;

}

} publicinterfaceIScheduledTask

{

publicAction GetAction;

publicDateTime? GetNextTime;

}

///<summary>

///定时器任务,普通任务

///间隔指定的时间

///</summary>

publicclassScheduledTask: IScheduledTask

{

privateAction _action;

privateTimeSpan timeSpan;

publicScheduledTask(Action action, TimeSpan timeSpan)

{

this._action = action;

this.timeSpan = timeSpan;

}

publicAction GetAction

{

returnthis._action;

}

publicDateTime? GetNextTime

{

returnDateTime.Now.AddSeconds(timeSpan.TotalSeconds);

}

}

最后的效果

在这里插入图片描述

当然,也可以通过CRON表达式来实现更为高级的。

后期再来个更高级一点的。 Github地址

https://github.com/kesshei/TimeWheelDemo



Tags:.Net   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
.Net开发中十种常见的内存错误以及相应的解决方案
在.Net开发中,为内存管理方面提供了许多便利,但仍然存在一些常见的错误和陷阱。这些错误可能导致内存泄漏、性能下降、异常抛出等问题,严重影响应用程序的稳定性和性能。在软件...【详细内容】
2024-03-26  Search: .Net  点击:(13)  评论:(0)  加入收藏
.NET配置文件大揭秘:轻松读取JSON、XML、INI和环境变量
概述:.NET中的IConfiguration接口提供了一种多源读取配置信息的灵活机制,包括JSON、XML、INI文件和环境变量。通过示例,清晰演示了从这些不同源中读取配置的方法,使配置获取变得...【详细内容】
2023-12-28  Search: .Net  点击:(92)  评论:(0)  加入收藏
.Net开发都应当掌握的泛型基础知识集合
在C#编程语言中,泛型是一项非常强大和重要的功能。它允许我们编写更加灵活和通用的代码,同时提高代码的可重用性和性能。本文将介绍C#泛型的一些关键知识点,帮助读者理解和应用...【详细内容】
2023-12-25  Search: .Net  点击:(125)  评论:(0)  加入收藏
作为 .NET 开发人员,我为什么开始使用 Python?
作者 | Alex Maher编译 | 小欧作为一名 .NET 开发人员,很长一段时间以来,我一直关注 C# 和 .NET 的出色工具和功能。但我最近开始使用 Python,感觉非常棒。这里申明一点,这篇文...【详细内容】
2023-12-25  Search: .Net  点击:(143)  评论:(0)  加入收藏
.NET领域性能最好的对象映射框架Mapster使用方法
Mapster是一个开源的.NET对象映射库,它提供了一种简单而强大的方式来处理对象之间的映射。在本文中,我将详细介绍如何在.NET中使用Mapster,并提供一些实例和源代码。和其它框架...【详细内容】
2023-12-22  Search: .Net  点击:(79)  评论:(0)  加入收藏
.NET Core 3.1 升级到 .NET 8,看看都有哪些变化
.NET Core 3.1 已经用了很长一段时间,其实在 2022 年的年底微软已经不提供支持了,后面的一个 LTS 版本 .NET 6 也会在 2024 年 11 月终止支持,所以直接升级到 .NET 8 是最好的...【详细内容】
2023-12-08  Search: .Net  点击:(192)  评论:(0)  加入收藏
.NET Core的中间件来对Web API进行流量限制实现方法
在.NET Core中,我们可以使用ASP.NET Core的中间件来对Web API进行流量限制。ASP.NET Core提供了一个名为RateLimit的开源库,可以方便地实现流量限制功能。下面将详细介绍如何...【详细内容】
2023-12-06  Search: .Net  点击:(177)  评论:(0)  加入收藏
微软官方出品微服务架构:十个.Net开源项目
1、一个高性能类型安全的.NET枚举实用开源库Enums.NET是一个.NET枚举实用程序库,专注于为枚举提供丰富的操作方法。它支持.NET Framework和.Net Core。它主要优点表现在类型...【详细内容】
2023-12-06  Search: .Net  点击:(133)  评论:(0)  加入收藏
.NET开源的处理分布式事务的解决方案
前言在分布式系统中,由于各个系统服务之间的独立性和网络通信的不确定性,要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务...【详细内容】
2023-11-30  Search: .Net  点击:(173)  评论:(0)  加入收藏
深入 .NET 异步编程:Task 与 ValueTask 的区别与选择
在 .NET 中,Task 和 ValueTask 都是用于表示异步操作的类型,但它们有一些重要的区别。TaskTask 是最常见的表示异步操作的类型。它通常用于表示耗时的、异步的操作,比如从文件...【详细内容】
2023-11-26  Search: .Net  点击:(190)  评论:(0)  加入收藏
▌简易百科推荐
.Net开发中十种常见的内存错误以及相应的解决方案
在.Net开发中,为内存管理方面提供了许多便利,但仍然存在一些常见的错误和陷阱。这些错误可能导致内存泄漏、性能下降、异常抛出等问题,严重影响应用程序的稳定性和性能。在软件...【详细内容】
2024-03-26  小乖兽技术  今日头条  Tags:.Net   点击:(13)  评论:(0)  加入收藏
.NET配置文件大揭秘:轻松读取JSON、XML、INI和环境变量
概述:.NET中的IConfiguration接口提供了一种多源读取配置信息的灵活机制,包括JSON、XML、INI文件和环境变量。通过示例,清晰演示了从这些不同源中读取配置的方法,使配置获取变得...【详细内容】
2023-12-28  架构师老卢  今日头条  Tags:.NET   点击:(92)  评论:(0)  加入收藏
.Net开发都应当掌握的泛型基础知识集合
在C#编程语言中,泛型是一项非常强大和重要的功能。它允许我们编写更加灵活和通用的代码,同时提高代码的可重用性和性能。本文将介绍C#泛型的一些关键知识点,帮助读者理解和应用...【详细内容】
2023-12-25  小乖兽技术  今日头条  Tags:.Net   点击:(125)  评论:(0)  加入收藏
作为 .NET 开发人员,我为什么开始使用 Python?
作者 | Alex Maher编译 | 小欧作为一名 .NET 开发人员,很长一段时间以来,我一直关注 C# 和 .NET 的出色工具和功能。但我最近开始使用 Python,感觉非常棒。这里申明一点,这篇文...【详细内容】
2023-12-25    51CTO  Tags:.NET   点击:(143)  评论:(0)  加入收藏
.NET Core 3.1 升级到 .NET 8,看看都有哪些变化
.NET Core 3.1 已经用了很长一段时间,其实在 2022 年的年底微软已经不提供支持了,后面的一个 LTS 版本 .NET 6 也会在 2024 年 11 月终止支持,所以直接升级到 .NET 8 是最好的...【详细内容】
2023-12-08  不止dotNET  微信公众号  Tags:.NET   点击:(192)  评论:(0)  加入收藏
.NET Core的中间件来对Web API进行流量限制实现方法
在.NET Core中,我们可以使用ASP.NET Core的中间件来对Web API进行流量限制。ASP.NET Core提供了一个名为RateLimit的开源库,可以方便地实现流量限制功能。下面将详细介绍如何...【详细内容】
2023-12-06  架构师老卢  今日头条  Tags:.NET   点击:(177)  评论:(0)  加入收藏
微软官方出品微服务架构:十个.Net开源项目
1、一个高性能类型安全的.NET枚举实用开源库Enums.NET是一个.NET枚举实用程序库,专注于为枚举提供丰富的操作方法。它支持.NET Framework和.Net Core。它主要优点表现在类型...【详细内容】
2023-12-06  编程乐趣  今日头条  Tags:.Net   点击:(133)  评论:(0)  加入收藏
.NET开源的处理分布式事务的解决方案
前言在分布式系统中,由于各个系统服务之间的独立性和网络通信的不确定性,要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务...【详细内容】
2023-11-30  追逐时光者  微信公众号  Tags:.NET   点击:(173)  评论:(0)  加入收藏
深入 .NET 异步编程:Task 与 ValueTask 的区别与选择
在 .NET 中,Task 和 ValueTask 都是用于表示异步操作的类型,但它们有一些重要的区别。TaskTask 是最常见的表示异步操作的类型。它通常用于表示耗时的、异步的操作,比如从文件...【详细内容】
2023-11-26  架构师老卢  微信公众号  Tags: .NET   点击:(190)  评论:(0)  加入收藏
.NET字符串存储:解析常量与动态字符串,深入了解内存机制
在 .NET 中,字符串是不可变的,这意味着一旦创建,字符串的内容就不能被修改。字符串在内存中以不同的方式存储,具体取决于它是常量字符串还是动态创建的字符串。常量字符串常量字...【详细内容】
2023-11-25  架构师老卢  微信公众号  Tags:.NET   点击:(196)  评论:(0)  加入收藏
站内最新
站内热门
站内头条