Если вы используете Java5 или новее, рассмотрите ScheduledThreadPoolExecutor
и Future
.В первом случае вы можете запланировать выполнение задач после определенной задержки или через определенные интервалы, таким образом, он принимает на себя роль Timer
, просто более надежно.
Средство Timer
управляет выполнением отложенных («запустить эту задачу через 100 мс») и периодических («запускать эту задачу каждые 10 мс») задач.Однако у Timer
есть некоторые недостатки, и ScheduledThreadPoolExecutor
следует рассматривать как его замену.[...]
A Timer
создает только один поток для выполнения задач таймера.Если задача таймера выполняется слишком долго, точность синхронизации других TimerTask
s может пострадать.Если повторяющаяся TimerTask
запланирована на выполнение каждые 10 мс, а другая TimerTask
занимает 40 мс для запуска, повторяющаяся задача либо (в зависимости от того, была ли она запланирована с фиксированной скоростью или с фиксированной задержкой) вызывается четыре раза в быстрой последовательности последлительное задание завершает или «пропускает» четыре вызова полностью.Пулы запланированных потоков устраняют это ограничение, позволяя вам предоставлять несколько потоков для выполнения отложенных и периодических задач.
Другая проблема с Timer
заключается в том, что он ведет себя плохо, если TimerTask
выдает непроверенное исключение.Поток Timer
не перехватывает исключение, поэтому непроверенное исключение, выброшенное из TimerTask
, завершает поток таймера.Timer
также не воскрешает поток в этой ситуации;вместо этого он ошибочно полагает, что все Timer
было отменено.В этом случае TimerTask
, которые уже запланированы, но еще не выполнены, никогда не запускаются, и новые задачи не могут быть запланированы.
С Параллелизм Java на практике , раздел 6.2.5.
И Future
с могут быть ограничены для запуска не более в течение указанного времени (выбрасывая TimeoutException
, если не удалось завершить время).
Обновление
Если вам не нравится вышеуказанное, вы можете настроить задачу на собственное время выполнения, как показано ниже:
int totalTime = 50000; // in nanoseconds
long startTime = System.getNanoTime();
boolean toFinish = false;
while (!toFinish)
{
System.out.println("Task!");
...
toFinish = (System.getNanoTime() - startTime >= totalTime);
}