java - 基于文本文件的火灾事件

标签 java multithreading time observer-pattern simulator

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

换句话说:

  1. 模拟器线程
    • 读取文件,发生时间戳时创建事件
  2. 工作线程
    • 处理数据(这是我们投入生产时将保留的代码)
  3. 事件切换/Notifier 线程??? (见下文)

我正在尝试找出如何最好地实现模拟器。对我来说,一次读取一行,然后 hibernate 几毫秒直到该事件发生,这似乎是错误的。有些事件的间隔小于 10 毫秒。我想做的是有一个事件队列,这样当事件相距很远时我就可以领先,这样当它们彼此接近时我要做的处理最少。

也许Simulator实际上应该是2个线程,一个读取文件并将事件放入队列中,另一个处理它们并向工作线程触发事件(参见上面的Notifier线程)。听起来合理吗?下面是一些代码,概述了我的想法。我走在正确的轨道上吗?这里不包括读取文件并创建 MyEvent 的线程。

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();
        }
    }
}

你觉得怎么样?很好,或者您会进行重大设计更改吗?

最佳答案

使用计时器时,最重要的是拥有一个能够在事件发生时触发事件的 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;
}

然后让计时器完成剩下的工作... 事实上,计时器将是模拟器线程。当然,它内部有线程。但是我不知道它的时间是否足够准确以满足您的需要。我只在多一秒或少一秒无关紧要的情况下使用它。我认为它计算了直到下一个事件的 sleep 时间。因此,它应该与您的解决方案一样准确。

关于java - 基于文本文件的火灾事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13166850/

相关文章:

multithreading - 使用更多线程时 OpenMP 性能最差(遵循 openMP 教程)

java - 多线程

date - 如何使用 HTML5 时间标签标记日期范围?

java - 如何使用 Java 在 Selenium WebDriver 中关闭子浏览器窗口

java - Twilio 如何在 SAY 循环中添加暂停

Python 和线程 - 如果运行多个进程,线程会慢慢消亡

ios - 时间字段和计算 - 最佳实践

linux - 为什么clock_gettime如此不稳定?

java - 得到递归方法的错误输出

java - JPA 存储库和阻塞 I/O