Akka定时任务schedule()方法
Akka定时任务schedule()方法
文章目录
- Akka定时任务schedule()方法
- 什么是Akka定时任务schedule()方法?
- 如何使用Akka定时任务schedule()方法?
- 如何在actor外部获取Scheduler对象
- 为什么需要提供一个隐式的ExecutionContext对象,用于执行定时任务?
- 如何在actor内部获取Scheduler对象
- schedule()方法的格式
- Akka定时任务schedule()方法有哪些类型的延迟?
- 固定延迟
- 固定频率
- Duration类
- 总结
什么是Akka定时任务schedule()方法?
Akka定时任务schedule()方法是一种在Akka actor系统中管理周期性执行任务的方式。它可以让我们在指定的时间点或时间间隔,向actor发送消息或执行函数。它返回一个Cancellable对象,我们可以调用它的cancel()方法来取消定时任务的执行。
Akka定时任务schedule()方法是基于一个哈希轮定时器(Hashed Wheel Timer)实现的,它是一种高效的数据结构和算法,用于处理大量的定时触发事件,如actor接收超时、Future超时、断路器等。它不会精确地在指定的时间点执行任务,而是在每个滴答(tick)时,执行所有已经到期的任务。我们可以通过配置属性akka.scheduler.tick-duration
来修改Akka定时任务schedule()方法的精度。
如何使用Akka定时任务schedule()方法?
如何在actor外部获取Scheduler对象
要使用Akka定时任务schedule()方法,我们需要先获取一个Scheduler对象,它是每个ActorSystem唯一的,并且用于内部调度各种事件。我们可以通过调用ActorSystem的scheduler方法来获取它:
// 获取一个ActorSystem对象
val system = ActorSystem("akka-scheduler-system")
// 获取一个Scheduler对象
val scheduler = system.scheduler
然后,我们需要提供一个隐式的ExecutionContext对象,用于执行定时任务。我们可以使用ActorSystem自带的dispatcher作为ExecutionContext:
// 导入ActorSystem自带的dispatcher作为ExecutionContext
import system.dispatcher
为什么需要提供一个隐式的ExecutionContext对象,用于执行定时任务?
ExecutionContext
是一个表示执行上下文的特质,它可以异步地执行程序逻辑,通常但不一定是在一个线程池上
。它类似于Java的Executor接口,它有两个抽象方法:execute和reportFailure
。execute方法
用于执行一个Runnable对象,reportFailure方法
用于报告一个异步计算失败的原因。
当我们使用Akka定时任务schedule()方法创建定时任务时,我们需要提供一个ExecutionContext对象,用于执行我们传入的函数或Runnable对象。这样,我们可以控制定时任务的执行策略,例如使用哪个线程池,如何处理异常等。我们可以使用ActorSystem自带的dispatcher作为ExecutionContext,也可以自定义一个ExecutionContext。
为了方便使用,我们通常会把ExecutionContext对象作为一个隐式参数传入schedule()方法。这样,我们就不需要显式地指定ExecutionContext对象,只需要在作用域内导入或定义一个隐式的ExecutionContext对象即可。例如:
// 导入ActorSystem自带的dispatcher作为隐式的ExecutionContext
import system.dispatcher
// 创建一个定时任务,不需要显式地传入ExecutionContext
scheduler.schedule(100.millis, 1.second)(() => greeter ! greet)
或者
// 定义一个自定义的ExecutionContext作为隐式的ExecutionContext
implicit val ec: ExecutionContext = ...
// 创建一个定时任务,不需要显式地传入ExecutionContext
scheduler.schedule(100.millis, 1.second)(() => greeter ! greet)
这样,我们就可以简化代码的书写和理解,同时保留了定时任务执行策略的灵活性。
如果我们不想使用隐式参数的方式来传入ExecutionContext对象,我们可以显式地指定ExecutionContext对象,只需要在schedule()方法的最后一个参数列表中加上ExecutionContext对象即可。例如:
// 定义一个自定义的ExecutionContext对象
val ec: ExecutionContext = ...
// 创建一个定时任务,显式地传入ExecutionContext对象
scheduler.schedule(100.millis, 1.second)(() => greeter ! greet)(ec)
这样,我们就可以显式地指定ExecutionContext对象,而不依赖于作用域内的隐式参数。这种写法可能会更清晰和安全,但也会增加代码的冗余和复杂度。因此,我们应该根据具体的场景和需求来选择是否使用隐式或显式的方式来传入ExecutionContext对象。
如何在actor内部获取Scheduler对象
context
是一个ActorContext对象
,它表示一个actor的上下文信息,包括它的self
引用,它的子actor
,它的监督策略
等。context也有一个system属性
,它是一个ActorSystem对象
,表示这个actor所属的actor系统
。因此,context.system.scheduler.schedule实际上就是调用这个actor所属的actor系统的scheduler方法来创建定时任务。
这种写法通常出现在actor内部
,当我们想要在actor内部创建定时任务
时,我们可以使用context.system.scheduler.schedule
来获取Scheduler对象。例如:
// 在actor内部创建一个定时任务,向自己发送HeartBeat消息
context.system.scheduler.schedule(100.millis, 1.second)(() => self ! HeartBeat)
这样,我们就不需要显式地获取或传入ActorSystem对象,只需要使用context.system即可。
schedule()方法的格式
接下来,我们可以使用Scheduler对象的schedule()方法来创建单次执行或重复执行的定时任务。这个方法有两种重载形式:
def schedule(initialDelay: FiniteDuration, interval: FiniteDuration)(f: ⇒ Unit): Cancellable
:这个方法用于创建重复执行的定时任务,它接受三个参数:初始延迟(initialDelay),表示第一次执行任务的延迟时间;间隔时间(interval),表示每次执行任务之间的时间间隔;函数(f),表示要执行的任务。它返回一个Cancellable对象,用于取消定时任务。def schedule(initialDelay: FiniteDuration, interval: FiniteDuration, receiver: ActorRef, message: Any): Cancellable
:这个方法用于创建重复向actor发送消息的定时任务,它接受四个参数:初始延迟(initialDelay),表示第一次发送消息的延迟时间;间隔时间(interval),表示每次发送消息之间的时间间隔;接收者(receiver),表示要发送消息给哪个actor;消息(message),表示要发送什么消息。它返回一个Cancellable对象,用于取消定时任务。
如果我们只想创建单次执行或单次发送消息的定时任务,我们可以将间隔时间设置为Duration.Zero。
Akka定时任务schedule()方法有哪些类型的延迟?
Akka定时任务schedule()方法有两种类型的延迟:固定延迟(fixed-delay)和固定频率(fixed-rate)。
固定延迟
固定延迟指的是两次连续的任务执行之间的延迟时间总是至少等于给定的间隔时间。下一次任务执行的时间只有在当前任务执行完成后才会计算。如果当前任务是一个长时间运行的任务,那么下一次任务执行会延迟。因此,两次连续的任务执行之间的时间差可能不是恒定的。
例如:
// 创建一个重复向actor发送消息的定时任务,初始延迟为100毫秒,间隔时间为1秒
scheduler.schedule(100.millis, 1.second, greeter, greet)
或者
// 创建一个重复执行函数的定时任务,初始延迟为10毫秒,间隔时间为250毫秒
scheduler.schedule(10.millis, 250.millis)(() => greeter ! greet)
注意,schedule()方法只能创建固定延迟的定时任务,如果我们想创建固定频率的定时任务,我们需要使用新的scheduleAtFixedRate()方法。
从Akka 2.6版本开始,schedule()方法已经被弃用,Akka建议我们使用scheduleWithFixedDelay()方法来创建固定延迟的定时任务。所以,我们可以重写前面的例子,使用scheduleWithFixedDelay()方法:
// 创建一个重复向actor发送消息的定时任务,初始延迟为100毫秒,间隔时间为1秒
scheduler.scheduleWithFixedDelay(100.millis, 1.second, greeter, greet)
或者
// 创建一个重复执行函数的定时任务,初始延迟为10毫秒,间隔时间为250毫秒
scheduler.scheduleWithFixedDelay(10.millis, 250.millis)(() => greeter ! greet)
固定频率
固定频率指的是两次连续的任务执行之间的时间差总是等于给定的间隔时间。下一次任务执行的时间是根据上一次任务执行的时间和间隔时间来计算的。如果当前任务是一个长时间运行的任务,那么下一次任务执行可能会立即开始,或者被跳过。因此,两次连续的任务执行之间的时间差可能是恒定的,也可能是零。
从Akka 2.6版本开始,Akka建议我们使用scheduleAtFixedRate()方法来创建固定频率的定时任务。所以,我们可以重写前面的例子,使用scheduleAtFixedRate()方法:
// 创建一个重复向actor发送消息的定时任务,初始延迟为100毫秒,间隔时间为1秒
scheduler.scheduleAtFixedRate(100.millis, 1.second, greeter, greet)
或者
// 创建一个重复执行函数的定时任务,初始延迟为10毫秒,间隔时间为250毫秒
scheduler.scheduleAtFixedRate(10.millis, 250.millis)(() => greeter ! greet)
Duration类
在上一篇利用akka模拟Spark的Master与Worker通信中,为什么那篇文章里的参数里面是Duration(3,TimeUnit.SECONDS),而不是这篇提供的这种。
Duration
是一个表示时间长度的类
,它有多种构造方法,可以接受不同类型的参数。这篇提供的那种参数是使用了一个隐式转换
,把一个数字和一个时间单位组合成一个Duration对象。例如:
// 使用隐式转换,把3秒转换为一个Duration对象
3.seconds
// 等价于
Duration(3, TimeUnit.SECONDS)
这种隐式转换是由scala.concurrent.duration包提供的,它可以让我们用更简洁和直观的方式来表示时间长度。我们需要导入这个包才能使用这种隐式转换:
// 导入scala.concurrent.duration包
import scala.concurrent.duration._
所以参数里面是Duration(3,TimeUnit.SECONDS)或者3.seconds都是可以的。
参数里面是Duration(3,TimeUnit.SECONDS)可能是因为没有导入这个包,或者是为了避免歧义,或者是为了保持一致性。它们的效果是一样的,只是写法不同而已。
总结
在这篇文章中,介绍了Akka定时任务schedule()方法,它是一种在Akka actor系统中管理周期性执行任务的方式。看到了如何使用schedule()方法来创建单次执行和重复执行的定时任务,以及它们的不同类型的延迟。还了解了Akka定时任务schedule()方法的实现原理和精度问题。
相关文章:

Akka定时任务schedule()方法
Akka定时任务schedule()方法 文章目录Akka定时任务schedule()方法什么是Akka定时任务schedule()方法?如何使用Akka定时任务schedule()方法?如何在actor外部获取Scheduler对象为什么需要提供一个隐式的ExecutionContext对象,用于执行定时任务&…...

Python实现处理和分析大规模文本数据集,包括数据清洗、标注和预处理
处理和分析大规模文本数据集,包括数据清洗、标注和预处理,是自然语言处理(NLP)中非常重要的一步。Python 是一种非常流行的编程语言,拥有丰富的 NLP 库和工具,可以帮助我们完成这些任务。以下是一个简单的实现示例,包括数据清洗、标注和预处理: import re import nltk…...

灌区量测水系统
1)灌区量测水 灌区量测水是水资源管理的基础,是推进节水农业和水价改革的重要手段。常规在主要水闸处,监测闸前和闸后水位及闸门开启状态(闸位),通过实时监测数据,计算过闸流量。要实现全灌区水资源动态配置、精准灌溉࿰…...

3.3 泰勒公式
学习目标: 复习微积分基础知识。泰勒公式是微积分的一个重要应用,因此在学习泰勒公式之前,需要复习微积分的基本概念和技能,包括函数的导数和微分、极限、定积分等。可以参考MIT的微积分课程进行复习和加强。 学习泰勒级数和泰勒…...

ubuntu中通过vscode编译调试ORB-SLAM3
为了在orb-slam3的基础上进行二次开发,这几天花了不少精力,终于搞懂怎么在ubuntu系统中像windows里visual studio中一样方便的打断点调试了,在这里把整个过程再重新梳理一下。 1 首先从安装ubuntu 22.04开始 因为是从实验室毕业先辈那里继承…...

阿里版 ChatGPT 突然上线!
转自:纯洁的微笑 其实早本月初,就传出过不少阿里要推出类ChatGPT的消息。 前几天率先流出的天猫精灵“鸟鸟分鸟”脱口秀版GPT,就是基于大模型的“压缩版”,已经以其惊艳表现吸引了众目光。 如今“原版大菜”上桌,自然一点即着&a…...

《Kubernetes部署篇:Ubuntu20.04基于containerd部署kubernetes1.24.12单master集群》
一、架构图 如下图所示: 二、环境信息 主机名K8S版本系统版本内核版本IP地址备注k8s-master-621.24.12Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.62master节点k8s-worker-631.24.12Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.63worker节点k8s-worker-641…...

MAZDA CX-50没现车怎么办?赶紧去VR看车啊!
爱车一族往往都有过这样的经历:听说某家品牌出了一款心仪的新车,于是一直心心念念想要先睹为快。然而这时候问题就来了:新车从发布到量产上市往往要经历一段过程。没有现车的日子里,就算每天去4S店蹲守也看不到新车。那种心里痒痒…...

结构体全解,适合初学者的一条龙深度讲解(附手绘图详解)
我们知道,C语言是允许我们自己来创造类型的,这些类型就叫做——自定义类型。 自定义类型又包括结构体类型,联合体类型还有枚举类型。 今天的文章,我们就着重讲解这其中的结构体类型。 目录 结构体的声明 1.1结构的基础知识 …...

什么是SD-WAN技术?企业网络优化的利器!
现今,企业网络架构已成为其发展不可或缺的组成部分。针对网络性能优化方面,SD-WAN是一种值得深思熟虑的选择,在企业网络中应用SD-WAN技术能够带来多重好处。 什么是SD-WAN技术以及它是如何工作的? SD-WAN是软件定义的广域网&…...

JAVA练习106- 生命游戏
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-生命游戏 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 4 月12日练习…...

【案例教程】基于R语言、MaxEnt模型融合技术的物种分布模拟、参数优化方法、结果分析制图与论文写作实践技术
【原文链接】: 基于R语言、MaxEnt模型融合技术的物种分布模拟、参数优化方法、结果分析制图与论文写作实践技术https://mp.weixin.qq.com/s?__bizMzU5NTkyMzcxNw&mid2247537049&idx3&sn31ef342c4808aed6fee6ac108b899a33&chksmfe6897f3c91f1ee5c4fa8e4eeea34…...

php7类型约束,严格模式
在PHP7之前,函数和类方法不需要声明变量类型 ,任何数据都可以被传递和返回,导致几乎大部分的调用操作都要判断返回的数据类型是否合格。 为了解决这个问题,PHP7引入了类型声明。 目前有两类变量可以声明类型: 形参&a…...

2023-04-11 无向图的匹配问题
无向图的匹配问题 之所以把无向图的这个匹配问题放到最后讲是因为匹配问题借鉴了有向图中一些算法的思想 1 最大匹配和完美匹配 二分图回顾 二分图:把一个图中的所有顶点分成两部分,如果每条边的两端分别属于不同部分,则这个图是二分图。更多…...

国家出手管人工智能AI了
我是卢松松,点点上面的头像,欢迎关注我哦! 全球都在封杀AI,国家也出手了,人工智能AI的强监管来了!这次反应速度算是很快了。国家出手,AI必须管。 国家网信办拟针对生成式人工智能服务出台管理办法&#…...

day24—选择题
文章目录1.将N条长度均为M的有序链表进行合并,合并以后的链表也保持有序,时间复杂度为(A)2.已知某个哈希表的n个关键字具有相同的哈希值,如果使用二次探测再散列法将这n个关键字存入哈希表,至少要进行&…...

自投递简历以来的第一次面试
投完简历之后HR小姐姐接着就安排了面试,原定时间是今天下午六点,我五点五十进的会议,结果等到六点二十(真的有点不耐烦了说实话)面试官打电话过来了说网络不是很好,所以改成电话面试了。 1、session信息保…...

【C++11】新特性 - 右值引用详解
文章目录STD容器使用右值引用场景移动语义在容器中的使用主要体现在两个方面:移动构造函数和移动赋值运算符。移动语义只对右值有效,对左值无效原因STD容器使用右值引用场景 移动语义在容器中的使用主要体现在两个方面:移动构造函数和移动赋…...

C++学习笔记
C学习笔记函数一般有返回值,构造函数有没有返回值?有返回值,返回一个对象,确定所以没写;在头文件中,防卫式声明,#ifndef…#define … #endif;pass by value或者 reference,传值是整包…...

项目1实现login登录功能方案设计第三版
需求优化点:MySQL表常用功能模块实现方案index页面home页面需求 实现一个登录功能 实现的功能 注册(邮箱注册)登录(邮箱密码)重置密码查看操作记录(登录, 注册, 重置密码, 登出. 都算操作)登出在第2版的基础上进行优化:\ 优化点: VerificationCode(验证码储存库): 增加时间字段…...

Node【七】初识Express框架
文章目录🌟前言🌟Express框架🌟1.什么是框架🌟2.express安装🌟3.创建web服务基本遵循之前的四个步骤:🌟4.路由🌟 由 :请求方式请求路径(1)get发送…...

Android 高通Camera2 Camera Device Close
1、很多人看到这个日志第一感觉可能觉得哪里没有合理释放,于是带着这个思路去进行百度探索 2、一开始我去寻找 ImageReader.OnImageAvailableListener 这个问题 var afterBitmap: Bitmap? null/**监听拍照的图片 */private val imageAvailableListener ImageRead…...

TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5
原文:Mobile Deep Learning with TensorFlow Lite, ML Kit and Flutter 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的…...

4、浅谈Makefile文件及其简单的使用知识
文章目录1、什么是Makefile?(1)makefile关系到了整个工程的编译规则。(2)makefile带来的好处就是——“自动化编译”(3)make是一个命令工具,是一个解释makefile中指令的命令工具2、为…...

5G/V2X赛道「重启」
在提升高阶智能驾驶安全性和感知冗余能力的道路上,除了激光雷达、高精度地图及定位,还有一项技术可能即将掀起一场新的风暴。 就在今年3月,作为全球通信领域的年度风向标 — 2023世界移动通信大会(MWC)上,…...

pytorch进阶学习(四):使用不同分类模型进行数据训练(alexnet、resnet、vgg等)
课程资源:5、帮各位写好了十多个分类模型,直接运行即可【小学生都会的Pytorch】_哔哩哔哩_bilibili 目录 一、项目介绍 1. 数据集准备 2. 运行CreateDataset.py 3. 运行TrainModal.py 4. 如何切换显卡型号 二、代码 1. CreateDataset.py 2.Train…...

Java面向对象高级【注解和反射】
目录 注解 什么是注解? 自定义注解 元注解 反射 什么是反射 静态语言和动态语言 动态语言 静态语言 对比 Class类 Java内存分析 类加载过程 类加载器 获取运行时类的完整结构 通过Class对象实例化对象 1.调用Class对象的newInstance 2.Constructor…...

Pytorch基础 - 4. torch.expand() 和 torch.repeat()
目录 1. torch.expand(*sizes) 2. torch.repeat(*sizes) 3. 两者内存占用的区别 在PyTorch中有两个函数可以用来扩展某一维度的张量,即 torch.expand() 和 torch.repeat() 1. torch.expand(*sizes) 【含义】将输入张量在大小为1的维度上进行拓展,…...

《LeetCode》——LeetCode刷题日记
本期,将给大家带来的是关于 LeetCode 的关于二叉树的题目讲解。 目录 (一)606. 根据二叉树创建字符串 💥题意分析 💥解题思路 (二)102. 二叉树的层序遍历 💥题意分析 &#…...

mysql数据库审计(1)
1.数据库审计工具介绍及选择 1.1. 数据库审计工具介绍 MySQL 分支的审计功能包含在企业版中,社区版可以使用其他分支提供的工具。目前已知的审计工具,社区版本有 Percona 的 Percona Server Audit Log 、MariaDB 的 MariaDB Audit Plugin 和 McAfee 的…...