需求: 如果我们想要使用Akka框架定时的执行一些任务,该如何处理呢?
答: 在Akka中,提供了一个scheduler对象来实现定时调度功能。使用ActorSystem.scheduler.schedule()方法,就可以启动一个定时任务
schedule
方式一: 采用发送消息的形式实现.
def schedule(
initialDelay: FiniteDuration, // 延迟多久后启动定时任务
interval: FiniteDuration, // 每隔多久执行一次
receiver: ActorRef, // 给哪个Actor发送消息
message: Any) // 要发送的消息
(implicit executor: ExecutionContext) // 隐式参数:需要手动导入
方式二: 采用自定义方式实现.
def schedule(
initialDelay: FiniteDuration, // 延迟多久后启动定时任务
interval: FiniteDuration // 每隔多久执行一次
)(f: ⇒ Unit) // 定期要执行的函数,可以将逻辑写在这里
(implicit executor: ExecutionContext) // 隐式参数:需要手动导入
注意: 不管使用上述的哪种方式实现定时器, 都需要导入隐式转换和隐式参数, 具体如下:
//导入隐式转换, 用来支持 定时器.
import actorSystem.dispatcher
//导入隐式参数, 用来给定时器设置默认参数.
import scala.concurrent.duration._
例子
需求
- 定义一个ReceiverActor, 用来循环接收消息, 并打印接收到的内容.
- 创建一个ActorSystem, 用来管理所有用户自定义的Actor.
- 关联ActorSystem和ReceiverActor.
- 导入隐式转换和隐式参数.
- 通过定时器, 定时(间隔1秒)给ReceiverActor发送一句话.
- 方式一: 采用发送消息的形式实现.
- 方式二: 采用自定义方式实现.
参考代码
//案例: 演示Akka中的定时器.
object MainActor {
//1. 定义一个Actor, 用来循环接收消息, 并打印.
object ReceiverActor extends Actor {
override def receive: Receive = {
case x => println(x) //不管接收到的是什么, 都打印.
}
}
def main(args: Array[String]): Unit = {
//2. 创建一个ActorSystem, 用来管理所有用户自定义的Actor.
val actorSystem = ActorSystem("actorSystem", ConfigFactory.load())
//3. 关联ActorSystem和ReceiverActor.
val receiverActor = actorSystem.actorOf(Props(ReceiverActor), "receiverActor")
//4. 导入隐式转换和隐式参数.
//导入隐式转换, 用来支持 定时器.
import actorSystem.dispatcher
//导入隐式参数, 用来给定时器设置默认参数.
import scala.concurrent.duration._
//5. 通过定时器, 定时(间隔1秒)给ReceiverActor发送一句话.
//方式一: 通过定时器的第一种方式实现, 传入四个参数.
//actorSystem.scheduler.schedule(3.seconds, 2.seconds, receiverActor, "你好, 我是种哥, 我有种子你买吗?...")
//方式二: 通过定时器的第二种方式实现, 传入两个时间, 和一个函数.
//actorSystem.scheduler.schedule(0 seconds, 2 seconds)(receiverActor ! "新上的种子哟, 你没见过! 嘿嘿嘿...")
//实际开发写法
actorSystem.scheduler.schedule(0 seconds, 2 seconds){
receiverActor ! "新上的种子哟, 你没见过! 嘿嘿嘿..."
}
}
}