Синхронизация нескольких таймеров для увеличения / уменьшения скорости - PullRequest
0 голосов
/ 03 июня 2011

У меня есть несколько экземпляров в моем приложении. Каждый из этих экземпляров имеет объект Timer, который через определенный промежуток времени запускает собственный метод объекта.

Поскольку это будет простое приложение для симуляции, я намерен разрешить ему иметь функцию имитации паузы / продолжения, а также функцию «увеличения / уменьшения скорости» для таймеров.

Однако, если все мои экземпляры имеют свои собственные отдельные объекты Timer, они все будут работать независимо самостоятельно, и будет сложно попросить все эти объекты приостановить и затем продолжить. Даже если бы я перебрал список массивов, чтобы вызывать все экземпляры для приостановки / продолжения таймера, это определенно не очень эффективный способ сделать что-то. Эта же проблема применима для увеличения и уменьшения общей скорости таймеров.

Кажется, у меня должен быть только один таймер в мире симуляции, который будет контролировать все экземпляры, но опять же, это также усложнит ситуацию.

Каковы некоторые из методов реализации для достижения таких требований? Я использую Java для своего приложения.

Спасибо!

Ответы [ 5 ]

3 голосов
/ 03 июня 2011

Вы всегда можете использовать подход, основанный на событиях. Сделайте так, чтобы каждый объект регистрировался как слушатель основного контроллера, а при изменении опции просто запускайте событие и позволяйте всем экземплярам обновляться самостоятельно.

0 голосов
/ 03 июня 2011

Вид зависит от того, сколько таймеров вам нужно. Конечно, вы можете реализовать список объектов timeout с событиями OnTimeout, которые обрабатывает один централизованный таймер. Один вопрос - стоит ли упорядочивать список по тайм-ауту? Если операции вставки / удаления / измененияTimeout немногочисленны, а количество «таймеров» велико, вы можете оставить список упорядоченным, а таймеру понадобится только тайм-аут элемента в начале списка. Один таймер высокого разрешения может обрабатывать сотни «таймеров» с высокой точностью. Недостатком является то, что insert / remove / changeTimeout требует переупорядочивания списка. Кроме того, если таймеры повторяются как системные таймеры, включенный таймер должен быть возвращен в список - еще одна операция вставки: (

Не уверен, оправдывает ли ваше приложение такую ​​сложность дельта-очереди.

Rgds, Martin

0 голосов
/ 03 июня 2011

Централизованный таймер - лучший способ, но я бы не стал этого делать из соображений эффективности, а потому, что это упростило бы обеспечение централизованного управления.

Одним из способов централизации этих таймеров является использование PriorityQueue. Вы можете добавить каждый таймер в приоритетную очередь и многократно получать следующий таймер из очереди. Для повторения задач добавьте в очередь еще раз. Вы можете играть в эти события с любой скоростью. ;)

Вы можете вызывать метод для десяти тысяч объектов за доли миллисекунды. Если это все, что вас беспокоит, возможно, вам не нужно менять.

0 голосов
/ 03 июня 2011

Поскольку это симуляция, может быть, есть лучший способ, чем запускать группу Timer с?Возможно, вы могли бы иметь одно представление «времени», которое может уведомить слушателей (или, проще говоря, список) через некоторое заданное время.

Итак, если ваш Timer должен отключиться через 5 секунд, тогдаэтот объединенный таймер будет уведомлять ваш объект через 5 тиков о его «времени».

Тогда у вас может быть один таймер, который просто выполняется с любой степенью детализации, которая вам нужна (например, 1 секунда представляет 1 тик).Таким образом, если вам нужно ускорить или замедлить симуляцию, то после того, как этот единственный Timer сработает, вы увеличиваете «тики», а не в реальном времени.Таким образом, скорость 50% увеличивается только на 0,5 тика каждую секунду.Скорость 200% увеличивается на 2 такта каждую секунду.

0 голосов
/ 03 июня 2011

Я бы определенно предложил пойти с одним центральным таймером.Кроме того, вы можете иметь один централизованный ArrayList, где вы можете зарегистрировать все объекты, которые должны быть запущены таймером.Объекты могут реализовывать интерфейс, скажем, ITimerInvokeable, с методом timerTick() или чем-то в этом роде.Когда таймер тикает, он может зацикливаться на ArrayList и вызывать timerTick() на всех объектах.В вычислительном отношении это не дороже, чем использование таймера в каждом объекте, так как в итоге вы получите одинаковое количество вызовов методов (и издержки цикла минимальны).Кроме того, вы сэкономите ресурсы, потому что у вас не работает куча таймеров.

(Это подход, основанный на событиях, и он похож на ответ @ Kyle, но, насколько я могу судить,он предлагает использовать события для распространения изменений в информации таймера.)

...