У меня есть код, где я планирую задачу, используя java.util.Timer
. Я огляделся и увидел, что ExecutorService
можно сделать то же самое. Итак, этот вопрос здесь, вы использовали Timer
и ExecutorService
для планирования задач, в чем преимущество одного использования над другим?
Также хотел проверить, использовал ли кто-нибудь Timer
класс и столкнулся с какими-либо проблемами, которые ExecutorService
решал для них.
Ответы:
Согласно Java параллелизма на практике :
Timer
может быть чувствительным к изменениям системных часов,ScheduledThreadPoolExecutor
не так.Timer
имеет только один поток выполнения, поэтому долго выполняющаяся задача может задержать выполнение других задач.ScheduledThreadPoolExecutor
можно настроить с любым количеством потоков. Кроме того, вы можете полностью контролировать созданные потоки, если хотите (предоставляяThreadFactory
).TimerTask
kill этого потока, делаютTimer
мертвым :-( ... т.е. запланированные задачи больше не будут выполняться.ScheduledThreadExecutor
Не только перехватывает исключения времени выполнения, но и позволяет вам обрабатывать их, если хотите (переопределениемafterExecute
метода fromThreadPoolExecutor
). Задача, которая исключение выбросить будет отменено, но другие задачи будут продолжать выполняться.Если вы можете использовать
ScheduledThreadExecutor
вместоTimer
, сделайте это.Еще одна вещь ... хотя
ScheduledThreadExecutor
она недоступна в библиотеке Java 1.4, есть Backport от JSR 166 (java.util.concurrent
) до Java 1.2, 1.3, 1.4 , который имеет этотScheduledThreadExecutor
класс.источник
Если это доступно для вас, то трудно придумать причину, по которой не следует использовать среду исполнения Java 5. Вызов:
даст вам
ScheduledExecutorService
схожую функциональностьTimer
(т.е. она будет однопоточной), но доступ к которой может быть немного более масштабируемым (под капотом он использует параллельные структуры, а не полную синхронизацию, как сTimer
классом). ИспользованиеScheduledExecutorService
также дает вам такие преимущества, как:newScheduledThreadPoolExecutor()
ИлиScheduledThreadPoolExecutor
класс)Единственные причины, по которым
Timer
я могу придерживаться :источник
TimerTask
может быть доступностьscheduledExecutionTime()
метода, который, кажется, не имеет никакого аналога вScheduledExecutorService
.ExecutorService является более новым и общим. Таймер - это просто поток, который периодически запускает то, что вы запланировали для него.
ExecutorService может быть пулом потоков или даже распространяться на другие системы в кластере и выполнять такие вещи, как одноразовое пакетное выполнение и т. Д.
Просто посмотрите, что каждый предлагает решить.
источник
Вот еще несколько полезных практик по использованию таймера:
http://tech.puredanger.com/2008/09/22/timer-rules/
В общем, я бы использовал Timer для быстрых и грязных вещей и Executor для более надежного использования.
источник
Со страницы документации Oracle на ScheduledThreadPoolExecutor
ExecutorService/ThreadPoolExecutor
илиScheduledThreadPoolExecutor
это очевидный выбор, когда у вас есть несколько рабочих потоков.Плюсы
ExecutorService
болееTimer
Timer
не могут воспользоваться преимуществами доступных ядер процессора в отличие отExecutorService
особенно с несколькими задачами , используя ароматыExecutorService
как ForkJoinPoolExecutorService
предоставляет совместный API, если вам нужна координация между несколькими задачами. Предположим, что вам нужно отправить N рабочих задач и дождаться завершения всех из них. Вы можете легко достичь этого с помощью invokeAll API. Если вы хотите добиться того же с несколькимиTimer
задачами, это было бы не просто.ThreadPoolExecutor предоставляет лучший API для управления жизненным циклом потока.
Несколько преимуществ:
а. Вы можете создавать / управлять / контролировать жизненный цикл потоков и оптимизировать накладные расходы на создание потоков
б. Вы можете контролировать обработку заданий (Work Stealing, ForkJoinPool, invokeAll) и т. Д.
с. Вы можете отслеживать прогресс и здоровье потоков
д. Обеспечивает лучший механизм обработки исключений
источник
Моя причина, по которой я иногда предпочитаю Timer, а не Executors.newSingleThreadScheduledExecutor (), заключается в том, что я получаю намного более чистый код, когда мне нужен таймер для выполнения в потоках демона.
сравнить
с участием
Я делаю это, когда мне не нужна надежность службы executor.
источник