在一个actor中使用Thread.sleep(5000);
是否正确?它实际上会让actor休眠5秒吗?有没有更简单的替代方法使actor休眠几秒钟?
在一个actor中使用Thread.sleep(5000);
是否正确?它实际上会让actor休眠5秒吗?有没有更简单的替代方法使actor休眠几秒钟?
在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
我认为与这个主题相关的帖子有点过时了,而且有些事情已经改变了。
以这个答案为起点: “不要在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();
}
}