Scala演员中的Thread.sleep

12

在一个actor中使用Thread.sleep(5000);是否正确?它实际上会让actor休眠5秒吗?有没有更简单的替代方法使actor休眠几秒钟?

2个回答

31

在Akka中不建议使用任何会阻塞线程的操作。如果Actor配置了共享线程池(默认行为),那么使用Thread.sleep将会阻止该线程池中的一个线程,而该线程本可以为其他Actor执行工作。

如果确实必须进行阻塞,则可以配置Actor拥有自己的线程。这可以通过为Actor配置自定义调度程序来实现,具体详细信息请参见此处

阻塞的替代方案是通过定时器安排回调函数发送消息给Actor,在一定时间后触发,例如5秒后。

akkaSystem.scheduler.scheduleOnce(5 seconds, actor, "msgFoo")

Akka调度器的文档在这里:http://doc.akka.io/docs/akka/2.3.6/scala/scheduler.html


非Akka的Actor怎么办? - As As
@AsAs,你使用的是哪种Actor实现?我想基本原理应该是相似的。 - Chris K
@AsAs 用的是哪个版本的Scala?2.11版本后,Scala开始使用Akka。请查看http://docs.scala-lang.org/overviews/core/actors-migration-guide.html。 - Chris K
早期的Scala Actors确实使用了共享线程池,但是我并不熟悉其详细信息。因此,如果一个Actor调用Thread.sleep,则会使与它共享该池的其他Actor饿死。 - Chris K

0

我认为与这个主题相关的帖子有点过时了,而且有些事情已经改变了。

以这个答案为起点: “不要在Actor内部使用sleep()!那会导致线程被阻塞,从而导致你试图避免的问题 - 使用资源。”

“相反,如果你只是处理消息并“什么也不做”,Actor将不会使用任何调度资源,并且只是堆上的另一个普通对象(占用一点内存但没有其他东西)。” 来自这篇文章:如何让actor休眠?

然后,这里是一个例子,可以让你获得与Thread.sleep()相同的行为:

在你想要“休眠”的Actor内部

  private void rescheduleActor() {
        // schedule to wake up
        logger.debug("rescheduleActor: Sleeping for 15 seconds");
        getContext().getSystem().scheduler().scheduleOnce(
                Duration.ofMillis(15000),
                getSelf(),
                new WakeUp(), getContext().getSystem().dispatcher(), null);

    }


  @Override
  public void onReceive(Object msg) { 

   if (msg instanceof WakeUp) {
            logger.debug("rescheduleDistributionTrackEntry: Resuming process.");
            methodToInvoke();
        }

}

更多细节请参见:https://doc.akka.io/docs/akka/2.5/scheduler.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接