1

研究案例: 我在 Swing 中有一个包含一些模型类和一些 GUI 类的程序,我在这两个类中都使用了几个线程,它们运行一个无限循环,每个可运行对象具有不同的睡眠间隔。两个模型线程运行一项非常关键的工作,如果延迟从 40 毫秒上升到 60 毫秒,将无法正常工作,因此它们非常关键。

但是我在 GUI 中有数百个组件必须在不到一秒或更频繁的时间内更新。这些组件无法使用观察者设计模式进行更新,因为它们不仅仅反映模型中的更改。他们应该计算诸如剩余时间之类的东西。

问题

  1. 我认为使用Runnable调用的数百个 sSwingUtilities.invokeLater(runnable)来更新所有 GUI 组件效率不高。因为上下文切换会产生巨大的副作用。所以我要避免它。我真的应该避免创建所有这些可运行对象,invokeLater()还是swing timer不将它们作为线程运行并且即使其中所有这些都具有优化方法Thread.sleep(500)
  2. 为了解决上述问题,我决定创建一个带有更新方法的接口 SwingUpdatable。并创建一个每 500 毫秒运行一次的 SingleTonSwingUpdater,并运行向其注册的类的所有更新方法。观察者设计模式让我想到了这个想法。但我担心这将是一种反模式。而且我不确定它是否会降低程序的灵活性。
  3. 如果我使用摇摆定时器怎么办。它肯定无法理解,如果 TimerTasks 都应该在 500 毫秒的时间间隔内运行,那么就不应该为它们创建一个新线程,并且在可运行对象上执行一个循环并一个接一个地执行它们就足够了。
  4. Java 是否有针对此问题的内置解决方案,或者是否有我可以使用的设计模式,或者我应该依赖最初看起来很脏的解决方案?
4

2 回答 2

1

好吧,如果你有一长串等待执行的 Runnables,那么在 EDT 上花费的时间将会增加,你的时间可能会变长。但是你至少应该做一个粗略的测试,看看这是否会发生。否则,您将尝试解决您没有的问题。

您也许可以尝试将事件合并在一起以避免做不必要的工作。最后一点,如果您的应用程序对时间非常敏感,那么您还需要注意垃圾收集(尽管这不应该是您首先担心的问题)。

于 2013-12-12T08:33:41.807 回答
1
  1. SwingUtilities.invokeLater(runnable) 在队列中添加runnable,然后GUI线程一次执行一个,因此上下文切换是最小的。避免在 GUI 线程上运行的作业中使用 Thread.sleep(),而是使用 Swing 计时器。

  2. 提议的“解决方案”增加了数据可视化的延迟,并且没有任何好处。小心为您不完全理解的问题添加解决方案。人类的直觉在计算机内部表现不佳。

  3. Swing 的计时器管理定时作业队列,并在延迟到期时将它们传递给 GUI 线程。这是一种非常有效的方法。

  4. 你在说什么问题?每秒数百个事件并没有那么多,标准方法应该可以工作。如果他们不这样做,他们可能被滥用了。

于 2013-12-12T08:54:21.133 回答