基于文本文件的触发事件

时间:2012-10-31 20:21:45

标签: java multithreading time observer-pattern simulator

我有一个包含事件记录的文本文件,每个事件都有一个时间戳。我想创建一个实时模拟文件数据的引擎。最终我的项目将使用实时数据,但我正在尝试创建一个测试框架。

换句话说:

  1. Simulator主题
    • 读取文件,在发生时间戳时创建事件
  2. Worker主题
    • 流程数据(这是我们进入生产时代码将保留)
  3. 事件切换/ Notifier线程??? (见下文)
  4. 我想弄清楚如何最好地实施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();
            }
        }
    }
    
    你怎么看?好,或者你会进行重大的设计变更吗?

1 个答案:

答案 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然后是模拟器线程。当然在内部它有线程。但是我不知道它的时间是否足以满足你的需要。我只使用它,或多或少无关紧要。而且我认为它会计算到下一次事件之前的睡眠时间。因此,它应该与您的解决方案一样精确。