我有这个数据流,大致是:
DataGenerator -> DataFormatter -> UI
DataGenerator 是一种快速生成数据的东西; DataFormatter 是为了显示目的而对其进行格式化的东西; UI 只是一堆 Swing 元素。
我想让我的 DataGenerator 像这样:
class DataGenerator
{
final private PropertyChangeSupport pcs;
...
public void addPropertyChangeListener(PropertyChangeListener pcl) {
this.pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
this.pcs.removePropertyChangeListener(pcl);
}
}
只要我的数据生成器有新数据,就调用this.pcs.firePropertyChange(...)
;然后我可以执行 dataGenerator.addPropertyListener(listener)
,其中 listener
负责将更改推送到 DataFormatter,然后推送到 UI。
这种方法的问题是,每秒有数千次 dataGenerator 更改(每秒 10,000 到 60,000 次,具体取决于我的情况),并且为 UI 格式化它的计算成本足够高,以至于它放置了一个不必要的加载到我的 CPU 上;实际上,我真正关心的是每秒最多 10-20 次变化。
有没有什么方法可以使用类似的方法,但在更改事件到达 DataFormatter 之前合并更改事件?如果我收到一个主题的多个更新事件,我只关心显示最新的,可以跳过所有之前的。
最佳答案
两个想法:
- 聚合
PropertyChangeEvent
。扩展PropertyChangeSupport
,覆盖public void firePropertyChange(PropertyChangeEvent evt)
,仅当最后一个事件在超过 50 毫秒(或任何合适的时间)前触发时触发。 (事实上 ,您应该覆盖每个fire*
方法,或者至少覆盖您在场景中使用的方法,以防止创建PropertyChangeEvent
。) - 放弃基于接近的整个事件。每秒 60.000 个事件是一个相当高的数字。在这种情况下,我会投票。这是对 MVP 的概念更改,其中演示者知道它是否处于 Activity 状态并且应该轮询。使用这种方法,您不会生成数以千计的无用事件;无论有多少数据,您甚至可以每秒显示尽可能高的帧数。或者您可以将演示器设置为固定速率,让它在刷新之间 hibernate 一段时间,或者让它适应其他情况(如 CPU 负载)。
我倾向于第二种方法。
关于Java + Swing : writing code to coalesce change events,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9202067/