预定函数未被调用

Scheduled function not being called

使用 Scala 将函数安排为每 X 秒 运行,这对我有用:

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global

object Driver {

  def main(args: Array[String]) {

   val system = akka.actor.ActorSystem("system")
   system.scheduler.schedule(0 seconds, 1 seconds)(println("beep"))

  }
}

此实现:

object Driver {

  def main(args: Array[String]) {

    val t = new java.util.Timer()
    val task = new java.util.TimerTask {
      def run() = println("Beep!")
    }

    t.schedule(task, 1000L, 1000L)
    task.cancel()
  }
}

import java.util.concurrent._

object Driver {

  def main(args: Array[String]) {

    val ex = new ScheduledThreadPoolExecutor(1)

    val task = new Runnable {
      def run() = println("Beep!")
    }

    val f = ex.scheduleAtFixedRate(task, 1, 1, TimeUnit.SECONDS)
    f.cancel(false)

  }
}

不要运行。它们只是挂起,不显示任何输出。是什么原因造成的?如果我调试代码,有时会出现 运行,所以这是与环境相关的问题?

java.util.Timer 的调度程序线程未 运行 作为守护线程,因此它可能会阻止应用程序终止。所以你应该

  1. 致电t.cancel(),或
  2. 创建您的计时器并将 isDaemon 设置为真: new java.util.Timer(true)

至于第二个例子,它基本上是相同的潜在问题,你应该调用 ex.shutdown() 来保持你的应用程序挂起。

我认为最好不要使用 Runnable 接口,而只使用带有 scala 的 akka 来完成你的工作。您必须使用 Cancellable 来安排任务,一种使用 actor 的简单而正确的方法是这样的

从 akka 文档中按如下方式操作

import akka.actor.Actor
import akka.actor.Props
import akka.util.duration._

    //Schedules to send the "foo"-message to the testActor after 50ms
    system.scheduler.scheduleOnce(50 milliseconds, testActor, "foo")

//Schedules a function to be executed (send the current time) to the testActor after 50ms
system.scheduler.scheduleOnce(50 milliseconds) {
  testActor ! System.currentTimeMillis
}

val Tick = "tick"
val tickActor = system.actorOf(Props(new Actor {
  def receive = {
    case Tick ⇒ //write here the function you want to execute
  }
}))


//This will schedule to send the Tick-message
//to the tickActor after 0ms repeating every 50ms
val cancellable =
  system.scheduler.schedule(0 milliseconds,
    50 milliseconds,
    tickActor,
    Tick)

//This cancels further Ticks to be sent
cancellable.cancel()

这是一个有效的完整示例:

使用 scala 2.11.6 和 akka 2.3.8

package org.example

import akka.actor.{ ActorSystem, Props, Actor }

import scala.concurrent.duration._
import scala.language.postfixOps

/**
 * Created by anquegi on 10/04/15.
 */
object ScheduledTaskScala extends App {

  //Use the system's dispatcher as ExecutionContext
  import system.dispatcher

  val system = ActorSystem.create("sheduledtask");

  val Tick = "tick"
  val tickActor = system.actorOf(Props(new Actor {
    def receive = {
      case Tick ⇒ { Thread.sleep(1000); println("I'm executing a task"); }
    }
  }))

  //This will schedule to send the Tick-message
  //to the tickActor after 0ms repeating every 2 s
  val cancellable =
    system.scheduler.schedule(0 milliseconds,
      2 seconds,
      tickActor,
      Tick)

  Thread.sleep(10000)

  cancellable.cancel()
}