我有一个包含事件记录的文本文件,每个事件都有一个时间戳。我想创建一个实时模拟文件数据的引擎。最终我的项目将使用实时数据,但我正在尝试创建一个测试框架。
换句话说:
Simulator
主题
Worker
主题
Notifier
线程??? (见下文)我想弄清楚如何最好地实施Simulator
。我一次读取一行似乎是错误的,然后睡觉直到该事件发生的毫秒数。有些事件间隔不到10毫秒。我想要做的是拥有一个事件队列,这样我就可以在事件相隔很远的情况下取得领先,这样我们在彼此靠近时就可以进行最少的处理。
也许Simulator
应该是2个线程,一个读取文件并将事件放入队列,另一个处理它们并将事件触发到工作线程(参见上文Notifier
线程)。这听起来合理吗?下面是一些代码,概述了我的想法。我是在正确的轨道上吗?这里不包括读取文件并创建MyEvent
s。
public class Notifier implements Runnable {
private long firstStartTime;
private long realStartTime;
private Worker theWorker;
public void run() {
while(true) {
if (eventQueue.peek().getTriggerTime() - this.firstStartTime >=
System.currentTimeMillis() - this.realStartTime) {
GlobalQueue.getInstance().offer(eventQueue.poll());
theWorker.notify();
}
}
}
}
public class GlobalQueue implements Queue<MyEvent> {
private Queue<MyEvent> myQueue;
private static GlobalQueue _instance = new GlobalQueue();
private GlobalQueue() {
myQueue = new LinkedList<MyEvent>();
}
public static getInstance() { return _instance; }
}
public class Worker implements Observer, Runnable {
public void run() {
while(true) {
if(events.peek() != null) {
MyEvent event = GlobalQueue.getInstance().poll();
// handle the event
}
wait();
}
}
}
你怎么看?好,或者你会进行重大的设计变更吗?
答案 0 :(得分:1)
使用Timer最重要的是有一个能够触发事件的TimerTask:
public class EventFirer extends TimerTask {
private final MyEvent event;
public EventFirer(MyEvent event) {
this.event = event;
}
public void run() {
event.fire();
}
}
现在您只需将所有EventFirers放入计时器:
public Timer fillTimer(List<Date> firingTimes) {
Timer timer = new Timer();
for (Date whenToFire: firingTimes) {
timer.schedule(new EventFirer(new MyEvent()), whenToFire);
}
return timer;
}
然后让Timer完成其余的工作...... 实际上Timer然后是模拟器线程。当然在内部它有线程。但是我不知道它的时间是否足以满足你的需要。我只使用它,或多或少无关紧要。而且我认为它会计算到下一次事件之前的睡眠时间。因此,它应该与您的解决方案一样精确。