UPDATE: Здесь моя реализация хешированных хронометров. Пожалуйста, дайте мне знать, если у вас есть идея улучшить производительность и concurrency. (20-Jan-2009)
// Sample usage:
public static void main(String[] args) throws Exception {
Timer timer = new HashedWheelTimer();
for (int i = 0; i < 100000; i ++) {
timer.newTimeout(new TimerTask() {
public void run(Timeout timeout) throws Exception {
// Extend another second.
timeout.extend();
}
}, 1000, TimeUnit.MILLISECONDS);
}
}
ОБНОВЛЕНИЕ. Я решил эту проблему, используя Иерархические и хэш-хромированные колеса. (19-Jan-2009)
Я пытаюсь реализовать таймер специального назначения в Java, который оптимизирован для обработки таймаута. Например, пользователь может зарегистрировать задачу с мертвой линией, и таймер может уведомить метод обратного вызова пользователя, когда мертвая линия завершена. В большинстве случаев зарегистрированная задача будет выполнена в течение очень короткого промежутка времени, поэтому большинство задач будут отменены (например, task.cancel()) или перенесены в будущее (например, task.rescheduleToLater(1, TimeUnit.SECOND)).
Я хочу использовать этот таймер для обнаружения соединения без подключения к сокету (например, закрыть соединение, если сообщение не получено в течение 10 секунд) и тайм-аут записи (например, вызвать исключение, когда операция записи не будет завершена через 30 секунд). в большинстве случаев тайм-аут не произойдет, клиент отправит сообщение, и ответ будет отправлен, если не возникнет странная проблема с сетью.
Я не могу использовать java.util.Timer или java.util.concurrent.ScheduledThreadPoolExecutor, потому что они предполагают, что большинство задач должны быть отключены. Если задача отменена, отмененная задача сохраняется во внутренней куче до тех пор, пока не вызывается ScheduledThreadPoolExecutor.purge(), и это очень дорогостоящая операция. (O (NlogN) возможно?)
В традиционных кучках или очередях приоритетов, которые я узнал в своих классах CS, обновление приоритета элемента было дорогостоящей операцией (O (logN) во многих случаях, потому что ее можно достичь только путем удаления элемента и повторной установки он имеет новое значение приоритета. Некоторые кучи, такие как куча Фибоначчи, имеют O (1) время операции уменьшенияKey() и min(), но мне нужно, по крайней мере, быстрое увеличениеKey() и min() (или уменьшениеKey() и max()).
Знаете ли вы какую-либо структуру данных, которая оптимизирована для этого конкретного случая использования? Одна из стратегий, о которой я думаю, - это просто хранить все задачи в хеш-таблице и повторять все задачи каждую секунду или около того, но это не так красиво.