【问题标题】:Loop a java application in ticks在滴答声中循环一个 java 应用程序
【发布时间】:2014-08-31 18:10:23
【问题描述】:

我正在制作一个 Java 服务器应用程序。如果应用程序在可能的情况下运行,它会消耗大量资源。

据我所知,如果我添加了一个 sleep 方法,它会像这样运行:

Do task (Might take 10ms to do. Can also take longer or less)
Sleep 50ms
Do task (Might take 10ms to do. Can also take longer or less)
Sleep 50ms

那么我怎样才能让它每 50 毫秒(20 滴答)运行一次?

谢谢

【问题讨论】:

  • 您能否说明您真正想要什么以及它与您的sleep 方法解决方案有何不同?
  • 立即尝试。 @SotiriosDelimanolis
  • 您是说希望下一次迭代每 50 毫秒运行一次,而不管前一个任务花费了多长时间?
  • 如果你正在编写一个服务器,它需要睡眠语句来提高性能,那么你做错了。在轮询任务队列之前,您应该将主循环设置为等到有任务要完成。如果您不熟悉完成此操作的原语,只需询问并提供有关您的服务器如何工作的更多详细信息。
  • @SotiriosDelimanolis 是的。因此,如果最后一个任务需要 10 毫秒,那么它会休眠 40 毫秒,或者如果最后一个任务需要 30 毫秒,那么它将休眠 20 毫秒。

标签: java ticker


【解决方案1】:

您可以使用ScheduledExecutorService

ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
service.scheduleAtFixedRate(() -> {
    System.out.println("whatever");
}, 0, 50, TimeUnit.MILLISECONDS);
   // ^ rate

scheduledAtFixedRate() 方法将安排给定任务以固定速率执行,而不管任务花费的时间。您可能有一个执行时间超过 50 毫秒,而下一个仍会运行(假设您有足够的线程)。

【讨论】:

  • 我希望它每秒运行 20 次。如果服务器过载,它将尝试每秒运行 20 次。
  • @user3854743 会的,是的。
  • @SotiriosDelimanolis 你确定吗? scheduleAtFixedRate() 的文档明确指出以下内容:“如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。”。听起来只是同时执行不同的任务,而不是同一个任务。
  • @elsamuray7 我猜 try 是他们评论中的关键词。老实说,我不记得了。不过,您对 javadoc 的看法是绝对正确的。
  • @SotiriosDelimanolis 是的,我实际上阅读了一些其他线程,而且根据我自己的经验,似乎永远不会同时执行相同的注册任务。
【解决方案2】:

在不知道您的应用程序做什么的情况下(您可以将其包含在您的问题中),您可以使用调度程序(Quartzjava.util.Timer)。您每 50 毫秒尝试执行哪个任务?

编辑:

虽然“游戏循环”在游戏中一切都很好,但服务器很少有它们。接收数据是一个持续的动作,状态也应该随之改变。这是服务器中一个更大的设计问题。通过适当的设计,您无需制造人为的停顿。

例如,一个简单的设计是让线程等待接收来自客户端的输入,当接收到消息时,会对其进行处理,并向所有客户端发送消息以通知更改。不要忙着等待,除非有消息来自客户端,否则什么都不会发生。

【讨论】:

  • 它是一个游戏服务器平台。所以基本上每个滴答声都很多。接收数据、发送数据、计算位置等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多