2012-10-31 24 views
1

我有一個包含事件記錄的文本文件,每個事件都有一個時間戳記。我想創建一個引擎,實時模擬文件中的數據。最終,我的項目將與實時數據一起工作,但我正在嘗試創建一個測試框架。基於文本文件的火災事件

換句話說:

  1. Simulator螺紋
    • 讀取文件,創建事件時戳發生
  2. Worker螺紋
    • 過程數據(這是代碼將保持時我們去製作)
  3. 事件切換/ Notifier線程??? (見下)

我想弄清楚如何最好地實施Simulator。我一次讀一行似乎是錯誤的,然後睡眠毫秒數直到發生此事件。有些事件相距不到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(); 
     } 
    } 
} 

您怎麼看?好,還是你會做重大的設計更改?

+0

你有沒有試過[計時器](http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html)?我認爲在這裏可以適合。 –

+0

你能詳細說一下嗎? – durron597

回答

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

然後讓定時器做其餘的事... 事實上,定時器將是模擬器線程然後。當然它有它的線程。不過,我不知道它的時機是否足夠滿足您的需求。我只在一秒或多或少沒有影響的地方使用它。我認爲它會計算下一次事件的時間。因此,它應該像你的解決方案一樣敏捷。