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.

Foi útil?

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 (fornecendo ThreadFactory).
  • exceções de tempo de execução jogado em Kill TimerTask que um fio, tornando assim Timer 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étodo afterExecute de ThreadPoolExecutor). 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 classe ScheduledThreadPoolExecutor)
  • 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ível Temporizador 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

  1. Timer não pode tirar vantagem de núcleos de CPU disponíveis, ao contrário ExecutorService especialmente com múltiplas tarefas usando sabores de ExecutorService como ForkJoinPool
  2. 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 tarefas Timer, seria não é simples.
  3. 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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top