关于Java中调度的良好实践

关于Java中调度的良好实践,java,scheduling,Java,Scheduling,我正在用Java从头开始构建一个游戏,只使用标准库。到目前为止,我已经有了一个在swing窗口中打印ASCII字符以表示3d对象的游戏。很酷。无论如何,由于我不知道线程或调度,我想知道我是否使用了一些可能导致以后出现问题的坏做法。我有一个重复的任务,每十分之一秒更新一次等级,但每当我想延迟某件事时,我就使用 Executors.newScheduledThreadPool(1).schedule... etc etc. 每当我想让一个新的延迟任务运行一次时,创建一个“新的调度线程池”是好的,还

我正在用Java从头开始构建一个游戏,只使用标准库。到目前为止,我已经有了一个在swing窗口中打印ASCII字符以表示3d对象的游戏。很酷。无论如何,由于我不知道线程或调度,我想知道我是否使用了一些可能导致以后出现问题的坏做法。我有一个重复的任务,每十分之一秒更新一次等级,但每当我想延迟某件事时,我就使用

Executors.newScheduledThreadPool(1).schedule... etc etc.

每当我想让一个新的延迟任务运行一次时,创建一个“新的调度线程池”是好的,还是应该让一个实例继续运行?如果重用实例比较好,那么什么时候创建一个新实例比较合适?

Swing应用程序中的并发性比较棘手:影响GUI的所有内容都需要在单个线程(称为事件调度线程)上执行。因此,当您设置一个单独的线程来执行一些长时间运行的后台任务(例如,为播放器尚未查看的区域生成地图)时,您需要小心地与可能影响GUI的任何内容进行同步

通常,对于更简单的用例,您有两个选项:

  • 如果这是一个短活动,会立即影响GUI,则使用
    计时器
    在事件调度线程上触发事件。看
  • 如果是长时间活动,则使用
    SwingWorker
    。看

有很多其他方法可以实现与其他线程的交互(例如,请参阅
SwingUtilities.invokeLater
SwingUtilities.invokeAndWait
),但是如果您已经说过您刚刚开始,我建议现在就坚持这两种方法之一。它们为您解决了大部分复杂问题,让您专注于游戏逻辑。

在Swing中,最好使用Swing
计时器。另一种解决方案可能是使用自定义
线程
。在这两种情况下,您都会让它们以“常规”间隔执行(在线程中使用
sleep
,以减少开销)。这三种情况中的任何一种都必须明白,这些机制只能保证“至少”精确性——也就是说,它们只能“延迟”指定的“至少”时间,但通常更长。“答案”是——视情况而定。我认为使用
Executors
来实现这一目的是不寻常的,它们可能无法提供您真正想要的准确度。您已经阅读了一些关于Java并发性的教程了吗?在最新版本中,它发生了很大变化,针对大多数常见用例的解决方案更加简单。我还认为
Executors.newScheduledThreadPool(1).schedule
是个坏主意,因为您应该保留对您创建的第一个executor的引用并重新使用它,否则您将面临多个线程同时执行的风险谢谢您的回答。不过,我不确定我是否会将其称为swing应用程序。最初它实际上只是在System.outs中渲染所有内容。现在它使用一个swing窗口、一个文本面板和一个更新它的方法。我的其他任务都没有直接与swing窗口交互,它只是游戏逻辑的东西。也就是说,所有这些swing内容仍然相关吗?@Freelix2000是的,swing内容仍然相关。即使只有一个Swing窗口,它仍然是一个Swing应用程序,这意味着您需要小心更新GUI的线程。我建议您从
定时器开始,如果这会导致问题,请查看其他选项。只有一个线程更新GUI,我想我永远不会再做另一个线程。这就是为什么这是一个更一般的日程安排问题,而不是摇摆问题。不过,我肯定会研究swing定时器,也许会在我已经写的东西中切换到它们。谢谢你的帮助。