预定的功能未被调用

时间:2015-04-10 11:06:50

标签: scala akka

使用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)

  }
}

不要跑。它们只是挂起而没有显示输出。可能是什么导致了这个?如果我调试代码然后它似乎有时运行,所以这是与环境相关的问题?

2 个答案:

答案 0 :(得分:1)

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

  1. 致电t.cancel()
  2. 使用isDaemon设置为true来创建计时器: new java.util.Timer(true)
  3. 至于第二个例子,它基本上是同一个底层问题,你应该调用ex.shutdown()来保持你的应用程序挂起。

答案 1 :(得分:1)

我认为最好不要使用界面Runnable并且只使用带scala的akka​​来完成工作。您必须使用可取消的可调度任务,使用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()
}