Таймер Java против ExecutorService?
у меня есть код, где я планирую задачу с помощью java.util.timer
. Я огляделся и увидел ExecutorService
можно сделать то же самое. Так что этот вопрос здесь, вы использовали таймер и ExecutorService
планировать задачи, в чем преимущество одного над другим использованием?
также хотел проверить, если кто-то использовал Timer
класс и столкнулся с любыми проблемами, которые ExecutorService
решены для них.
6 ответов:
по данным параллелизм Java на практике:
Timer
может быть чувствительным к изменениям в системных часах,ScheduledThreadPoolExecutor
нет.Timer
имеет только один поток выполнения, поэтому длительная задача может задерживать другие задачи.ScheduledThreadPoolExecutor
можно настроить с любым количеством потоков. Кроме того, у вас есть полный контроль над созданными потоками, если вы хотите (предоставивThreadFactory
).- исключения во время выполнения брошены в
TimerTask
убейте его нить, таким образом делаяTimer
dead : - ( ... т. е. запланированные задачи больше не будут выполняться.ScheduledThreadExecutor
не только ловит исключения во время выполнения, но и позволяет обрабатывать их, если вы хотите (путем переопределенияafterExecute
методThreadPoolExecutor
). Задача, которая вызвала исключение, будет отменена, но другие задачи будут продолжать выполняться.если вы можете использовать
ScheduledThreadExecutor
вместоTimer
, это сделать.еще одна вещь... в то время как
ScheduledThreadExecutor
не доступен в библиотеке Java 1.4, есть Backport JSR 166 (java.util.concurrent
) С Java 1.2, 1.3, 1.4, которая имеетScheduledThreadExecutor
класса.
если это доступно для вас, то трудно придумать причину не для использования Java 5 executor framework. Звоню:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
даст вам
ScheduledExecutorService
С аналогичной функциональностью дляTimer
(т. е. он будет однопоточным) , но доступ к которому может быть немного более масштабируемым (под капотом он использует параллельные структуры, а не полную синхронизацию, как сTimer
класс). ИспользуяScheduledExecutorService
также дает вам такие преимущества как:
- вы можете настроить его в случае необходимости (см.
newScheduledThreadPoolExecutor()
илиScheduledThreadPoolExecutor
класс)- выполнение "one off" может возвращать результаты
о единственных причинах придерживаться
Timer
Я могу думать, являются:
- он доступен до Java 5
- аналогичный класс предоставляется в J2ME, что может упростить перенос вашего приложения (но было бы не так уж сложно добавить общий уровень абстракции в данном случае)
ExecutorService является более новым и более общим. Таймер-это просто поток, который периодически запускает вещи, которые вы запланировали для него.
ExecutorService может быть пулом потоков или даже распределяться по другим системам в кластере и выполнять такие действия, как одноразовое пакетное выполнение и т. д...
просто посмотрите, что каждый предлагает решить.
вот еще несколько хороших практик вокруг использования таймера:
http://tech.puredanger.com/2008/09/22/timer-rules/
В общем, я бы использовал таймер для быстрого и грязного материала и исполнителя для более надежного использования.
моя причина иногда предпочитают таймер над исполнителями.newSingleThreadScheduledExecutor () заключается в том, что я получаю гораздо более чистый код, когда мне нужен таймер для выполнения в потоках демонов.
сравнить
private final ThreadFactory threadFactory = new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true); return t; } }; private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory);
С
private final Timer timer = new Timer(true);
Я делаю это, когда мне не нужна надежность executorservice.
со страницы документации Oracle на ScheduledThreadPoolExecutor
A ThreadPoolExecutor это может дополнительно запланировать команды для запуска после заданной задержки или для периодического выполнения. Этот класс предпочтительнее таймер когда требуется несколько рабочих потоков, или когда требуется дополнительная гибкость или возможности ThreadPoolExecutor (который этот класс расширяет).
ExecutorService/ThreadPoolExecutor
илиScheduledThreadPoolExecutor
- это очевидный выбор, когда у вас есть несколько рабочих потоков.плюсы
ExecutorService
overTimer
Timer
не может воспользоваться доступными ядрами процессора в отличие отExecutorService
особенно с несколькими задачами, используя ароматыExecutorService
как ForkJoinPoolExecutorService
обеспечивает совместный API, если вам нужна координация между несколькими задачами. Предположим, что вам нужно отправить N рабочих задач и дождаться завершения из всех них. Вы можете легко достичь этого с invokeAll API. Если вы хотите достичь того же с несколькимиTimer
задачи, было бы не просто.ThreadPoolExecutor обеспечивает лучший API для управления жизненным циклом потока.
пулы потоков решают две различные проблемы: они обычно обеспечивают повышенную производительность при выполнении большого количества асинхронных задач из-за уменьшения вызова каждой задачи накладные расходы, и они обеспечивают средства ограничения и управления ресурсами, включая потоки, потребляемые при выполнении коллекции задач. Каждый ThreadPoolExecutor также поддерживает некоторые основные статистические данные, такие как количество выполненных задач
преимущества:
a. Вы можете создавать/управлять / контролировать жизненный цикл потоков и оптимизировать затраты на создание потоков
b. вы можете управлять обработкой задач ( Work Stealing, ForkJoinPool, invokeAll) так далее.
c. вы можете следить за ходом и состоянием потоков
d. обеспечивает лучший механизм обработки исключений