1

それぞれにタイムスタンプが付いたイベントの記録を含むテキスト ファイルがあります。ファイルからのデータをリアルタイムでシミュレートするエンジンを作成したいと考えています。最終的に私のプロジェクトはライブ データで動作しますが、テスト フレームワークを作成しようとしています。

言い換えると:

  1. Simulatorスレッド
    • ファイルを読み取り、タイムスタンプが発生したときにイベントを作成
  2. Workerスレッド
    • プロセス データ (これは、本番環境に移行したときに残るコードです)
  3. イベントハンドオフ/Notifierスレッド??? (下記参照)

を実装する最善の方法を見つけようとしていますSimulator。一度に 1 行ずつ読み取ってから、そのイベントが発生するまでミリ秒数スリープするのは間違っているように思えます。一部のイベントの間隔は 10 ミリ秒未満です。私がやりたいのは、イベントが遠く離れているときに先に進むことができるように、イベントキューを用意することです。これにより、イベントが互いに近くにあるときに実行する処理を最小限に抑えることができます。

おそらくSimulator実際には 2 つのスレッドである必要があります。1 つはファイルを読み取り、イベントをキューに入れ、もう 1 つはそれらを処理し、ワーク スレッドにイベントを発生させます (上記の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();
        }
    }
}

どう思いますか?いいですか、それとも大幅な設計変更を行いますか?

4

1 に答える 1

1

タイマーを使用する場合、イベントを発生させることができる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;
}

そして、残りはタイマーに任せましょう...実際、タイマーはシミュレータースレッドになります。もちろん、内部的にはスレッドがあります。しかし、そのタイミングがあなたが必要とするものに対して十分に正確であるかどうかはわかりません。私はそれを多かれ少なかれ問題にならない場所でのみ使用しました。そして、次のイベントまでの睡眠時間を計算していると思います。そのため、ソリューションと同じくらい正確である必要があります。

于 2012-10-31T22:01:15.203 に答える