2011-06-03 71 views
0

我在我的應用程序中有幾個實例。這些實例中的每一個都有一個Timer對象,它會在一段時間後觸發對象自己的方法。因爲這將是一個簡單的模擬應用程序,我打算讓它具有暫停/繼續模擬功能以及定時器的「升降速」功能。但是,如果我的所有實例都有各自的Timer對象,它們將全部獨立運行,很難要求所有這些對象暫停然後繼續。即使我要遍歷數組列表以調用每個實例來暫停/繼續它的計時器,但這絕對不是一種非常有效的方法。同樣的問題適用於提高和降低定時器的整體速度。同步多個定時器以提高/降低速度

看起來我似乎應該在模擬世界中只有一個計時器來控制所有的實例,但這又會讓事情變得非常複雜。

實現這些要求的一些實現方法是什麼?我正在爲我的應用程序使用Java。

謝謝!

+0

@ 125取決於您是否使用javax.swing.Timer或java.util.Timer, – mKorbel 2011-06-03 17:07:14

回答

3

你總是可以使用事件驅動的方法。讓每個對象都註冊爲主控制器的偵聽器,並且在更改選項時,只需觸發一個事件並讓所有實例自行更新即可。

+0

爲了讓每個實例在與其他實例不同的時間執行某些操作,我的主控制器會仍然需要有多個定時器?或者我錯過了什麼?謝謝。 – Carven 2011-06-04 07:14:27

0

我肯定會建議去一箇中央計時器。另外,您可以有一個集中的ArrayList,您可以在其中註冊需要由定時器觸發的所有對象。這些對象可以實現一個接口,例如,ITimerInvokeable,方法timerTick()或沿着這些線的東西。當計時器滴答時,它可以遍歷ArrayList並在所有對象上調用timerTick()。從計算上來說,這並不比在每個對象中使用計時器更昂貴,因爲您最終會得到相同數量的方法調用(並且循環開銷最小)。另外,由於沒有大量定時器運行,您將節省資源。

(這是一個事件驅動的方法和類似於@凱爾的答案,但據我所知,他提出利用事件來傳播的計時器信息的變化。)

+0

通過這樣做,所有的實例是否只在一次調用一起?一個原因wh我每個對象都有一個計時器,每個對象都在不同時間運行其他對象的內部方法。 – Carven 2011-06-03 17:08:32

+0

@xEnOn:哦;我以爲一切都應該在同一時間發生。如果不同對象的計時器時間間隔需要不同,或者需要彼此不同步,那麼您可能確實需要單獨的計時器,因此您應該考慮Kyle的建議。 – 2011-06-03 17:24:52

0

由於這是一個模擬,也許有比推出一堆Timer s更好的方法嗎?也許你可以有一個「時間」的表示,可以在一段預設的時間後通知聽衆(或者更簡單的說是一個列表)。

因此,如果Timer應在5秒鐘後關閉,那麼統一時間持有者將在其「時間」的5個刻度後通知您的對象。然後,您可以有一個計時器,它可以根據您需要的任何粒度執行(例如,1秒代表1次計時)。這樣,如果您需要加快或減慢模擬速度,那麼在單個Timer熄滅後,您將增加「滴答」而不是實時。所以,50%的速度每秒只會上升0.5個滴答聲。 200%速度每秒增加2個滴答聲。

0

集中計時器是最好的方法,但我不會爲了效率的原因這麼做,而是因爲它可以簡化集中控制。

集中這些定時器的一種方法是使用PriorityQueue。您可以將每個定時器添加到優先級隊列,並重復從隊列中獲取下一個定時器。對於重複任務,請再次添加到隊列中。您可以以任何您想要的速度播放這些活動。 ;)

您可以在幾分之一毫秒內調用一萬個對象的方法。如果這是你所擔心的一切,也許你不需要改變。

0

有點取決於你需要多少個定時器。您當然可以通過一箇中央計時器處理的'OnTimeout'事件實現一個超時對象列表。一個問題是 - 是否值得按照超時時間排序?如果insert/remove/changeTimeout操作很少,並且'定時器'的數量很大,您可以保持列表的排列順序,並且定時器只需要超時列表頭部的項目。一個高分辨率定時器可以高精度處理數百個'定時器'。缺點是insert/remove/changeTimeout需要重新排列列表。另外,如果定時器重複類似系統定時器,定時器發射已被放回名單上 - 另一個插入操作:(

不知道如果你的應用程序證明這種三角隊列的複雜性

。 Rgds, Martin