Java Temporizador vs ExecutorService?
-
03-07-2019 - |
Pergunta
Eu tenho o código onde eu agendar uma tarefa utilizando java.util.timer
. Eu estava olhando em volta e viu ExecutorService
pode fazer o mesmo. Portanto, esta questão aqui, você usou temporizador e ExecutorService
para agendar tarefas, o que é o benefício de um usando detrimento de outro?
Também queria verificar se alguém tivesse usado a classe Timer
e correu para quaisquer questões que a ExecutorService
resolvidos por eles.
Solução
De acordo com a Java Concurrency in Practice :
-
Timer
podem ser sensíveis a mudanças no relógio do sistema,ScheduledThreadPoolExecutor
não é. -
Timer
tem apenas um thread de execução, de modo tarefa de longa duração pode atrasar outras tarefas.ScheduledThreadPoolExecutor
pode ser configurado com qualquer número de segmentos. Além disso, você tem total controle sobre tópicos criados, se você quiser (fornecendoThreadFactory
). - exceções de tempo de execução jogado em Kill
TimerTask
que um fio, tornando assimTimer
mortos :-( ... ou seja, tarefas agendadas não funcionará mais.ScheduledThreadExecutor
não só capturas tempo de execução exceções, mas ele permite que você lidar com eles se você quiser (substituindo métodoafterExecute
deThreadPoolExecutor
). Tarefa que jogou exceção será cancelada, mas outras tarefas continuará a funcionar.
Se você pode usar ScheduledThreadExecutor
vez de Timer
, fazê-lo.
Mais uma coisa ... enquanto ScheduledThreadExecutor
não está disponível em Java 1.4 biblioteca, há um Backport de JSR 166 (java.util.concurrent
) para Java 1.2, 1.3, 1.4 , que tem a classe ScheduledThreadExecutor
.
Outras dicas
Se estiver disponível para você, então é difícil pensar em uma razão não usar a estrutura executor Java 5. Chamar:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
lhe dará uma ScheduledExecutorService
com funcionalidade semelhante ao Timer
(isto é, será de segmento ú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 com a classe Timer
). Usando um ScheduledExecutorService
também lhe dá vantagens, tais como:
- Você pode personalizá-lo se for necessário (ver a
newScheduledThreadPoolExecutor()
ou a classeScheduledThreadPoolExecutor
) - As execuções 'um fora' pode retornar resultados
Sobre as únicas razões para furar a Timer
eu posso pensar são:
- Está disponível pré Java 5
- Uma classe semelhante é fornecida no J2ME, que poderia fazer portar sua aplicação mais fácil (mas não seria terrivelmente difícil para adicionar uma camada comum de abstração, neste caso)
ExecutorService é mais recente e mais geral. Um temporizador é apenas um segmento que periodicamente executado coisas que você tem programado para ele.
Um ExecutorService pode ser um pool de threads, ou mesmo espalhadas por outros sistemas em um cluster e fazer coisas como lote one-off execução, etc ...
Basta olhar para o que cada um oferece para decidir.
Eis mais algumas boas práticas em torno do uso Timer:
http://tech.puredanger.com/2008/09/22 / temporizador-regras /
Em geral, eu usaria temporizador para o material rápida e suja e Executor para o uso mais robusto.
Minha razão para, por vezes, preferindo Temporizador sobre Executors.newSingleThreadScheduledExecutor () é que eu tenho um código mais limpo muito quando eu preciso o timer para executar em segmentos daemon.
comparar
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);
com
private final Timer timer = new Timer(true);
Eu faço isso quando eu não preciso a robustez de um ExecutorService.
A partir da página de documentação do Oracle em ScheduledThreadPoolExecutor
A
ThreadPoolExecutor que, adicionalmente, pode comandos de programação para executar depois de um determinado atraso, ou para executar periodicamente. Esta classe é preferívelTemporizador quando são necessários múltiplos segmentos de trabalho, ou quando a flexibilidade adicional ou capacidades de ThreadPoolExecutor (que esta classe estende) são necessários.
ExecutorService/ThreadPoolExecutor
ou ScheduledThreadPoolExecutor
é a escolha óbvia quando você tem vários segmentos de trabalho.
Pros de ExecutorService
mais Timer
-
Timer
não pode tirar vantagem de núcleos de CPU disponíveis, ao contrárioExecutorService
especialmente com múltiplas tarefas usando sabores deExecutorService
como ForkJoinPool -
ExecutorService
fornece API colaborativa se precisar de coordenação entre várias tarefas. Suponha que você tem que apresentar o número N de tarefas de trabalho e aguardar a conclusão de todos eles. Você pode facilmente alcançá-lo com invokeAll API. Se você deseja alcançar o mesmo com múltiplas tarefasTimer
, seria não é simples. -
ThreadPoolExecutor proporciona melhor API para gerenciamento do ciclo de vida thread.
Thread pools resolver dois problemas diferentes: eles geralmente fornecem um melhor desempenho durante a execução de um grande número de tarefas assíncronas, devido à redução da invocação per-tarefa em cima, e eles fornecem um meio de delimitadora e gestão dos recursos, incluindo tópicos, consumida durante a execução uma coleção de tarefas. Cada ThreadPoolExecutor também mantém algumas estatísticas básicas, tais como o número de tarefas concluídas
Poucos vantagens:
a. Você pode criar / gerir / ciclo de vida de controle de threads e criação de thread otimizar o custo despesas gerais
b. Você pode controlar o processamento de tarefas (Work Roubar, ForkJoinPool, invokeAll) etc.
c. Você pode monitorar o progresso ea saúde dos tópicos
d. Fornece melhor mecanismo de manipulação de exceção