Eu tenho código onde agendar uma tarefa usando java.util.Timer
. Eu estava olhando em volta e vi que ExecutorService
pode fazer o mesmo. Então, nesta pergunta, você usou Timer
e ExecutorService
para agendar tarefas, qual é o benefício de um usar em detrimento de outro?
Também queria verificar se alguém havia usado a Timer
classe e se deparou com algum problema que ExecutorService
eles resolvessem.
Respostas:
De acordo com a concorrência em Java na prática :
Timer
pode ser sensível a alterações no relógio do sistema,ScheduledThreadPoolExecutor
não é.Timer
possui apenas um encadeamento de execução; portanto, tarefas de longa duração podem atrasar outras tarefas.ScheduledThreadPoolExecutor
pode ser configurado com qualquer número de threads. Além disso, você tem controle total sobre os threads criados, se desejar (fornecendoThreadFactory
).TimerTask
matar esse segmento, tornandoTimer
inoperantes :-( ... ou seja, as tarefas agendadas não serão mais executadas.ScheduledThreadExecutor
Não apenas capturam exceções de tempo de execução, mas permitem lidar com elas se você quiser (substituindo oafterExecute
método deThreadPoolExecutor
). Tarefa que A exceção lançada será cancelada, mas outras tarefas continuarão em execução.Se você pode usar em
ScheduledThreadExecutor
vez deTimer
, faça-o.Mais uma coisa ... embora
ScheduledThreadExecutor
não esteja disponível na biblioteca Java 1.4, existe um Backport do JSR 166 (java.util.concurrent
) para o Java 1.2, 1.3, 1.4 , que possui aScheduledThreadExecutor
classe.fonte
Se estiver disponível, é difícil pensar em um motivo para não usar a estrutura do executor Java 5. A ligar:
fornecerá uma
ScheduledExecutorService
funcionalidade semelhante aTimer
(ou seja, será de thread único), mas cujo acesso pode ser um pouco mais escalável (sob o capô, ele usa estruturas simultâneas em vez de sincronização completa como naTimer
classe). O uso de umScheduledExecutorService
também oferece vantagens como:newScheduledThreadPoolExecutor()
aScheduledThreadPoolExecutor
classe ou )Sobre os únicos motivos pelos quais
Timer
posso me ater são:fonte
TimerTask
pode ser a disponibilidade doscheduledExecutionTime()
método que parece não ter nenhum equivalenteScheduledExecutorService
.ExecutorService é mais recente e mais geral. Um cronômetro é apenas um encadeamento que executa periodicamente as coisas que você agendou para ele.
Um ExecutorService pode ser um pool de encadeamentos ou mesmo se espalhar por outros sistemas em um cluster e fazer coisas como execução em lote única, etc ...
Basta olhar para o que cada um oferece para decidir.
fonte
Aqui estão mais algumas boas práticas sobre o uso do Timer:
http://tech.puredanger.com/2008/09/22/timer-rules/
Em geral, eu usaria o Timer para coisas rápidas e sujas e o Executor para um uso mais robusto.
fonte
Na página de documentação do Oracle no ScheduledThreadPoolExecutor
ExecutorService/ThreadPoolExecutor
ouScheduledThreadPoolExecutor
é uma escolha óbvia quando você tem vários threads de trabalho.Prós de
ExecutorService
mais deTimer
Timer
não pode tirar proveito dos núcleos de CPU disponíveis, ao contrário,ExecutorService
especialmente com várias tarefas usando tiposExecutorService
como o ForkJoinPoolExecutorService
fornece API colaborativa se você precisar de coordenação entre várias tarefas. Suponha que você precise enviar um número N de tarefas do trabalhador e aguardar a conclusão de todas elas. Você pode alcançá-lo facilmente com a API invokeAll . Se você deseja conseguir o mesmo com váriasTimer
tarefas, não seria simples.O ThreadPoolExecutor fornece uma API melhor para o gerenciamento do ciclo de vida do Thread.
Poucas vantagens:
uma. Você pode criar / gerenciar / controlar o ciclo de vida de Threads e otimizar os custos indiretos de criação de threads
b. Você pode controlar o processamento de tarefas (roubo de trabalho, ForkJoinPool, invokeAll) etc.
c. Você pode monitorar o progresso e a integridade dos threads
d. Fornece melhor mecanismo de tratamento de exceções
fonte
Meu motivo para às vezes preferir o Timer ao Executors.newSingleThreadScheduledExecutor () é que recebo um código muito mais limpo quando preciso que o timer seja executado nos threads do daemon.
comparar
com
Faço isso quando não preciso da robustez de um serviço executor.
fonte