Pergunta

Eu encontrei perguntas semelhantes perguntou aqui, mas não havia respostas para minha satisfação. Então reformular a pergunta novamente -

Eu tenho uma tarefa que precisa ser feito em uma base periódica (digamos intervalos de 1 minuto). Qual é a vantagem de usar TimerTask e temporizadores para fazer isso em vez de criar um novo segmento que tem um loop infinito com o sono?

Código snippet usando TimerTask -

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

Código snippet usando fio e dormir -

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

Eu realmente não precisa se preocupar se eu perder certos ciclos se a execução da lógica leva mais do que o intervalo de tempo.

Por favor, comente sobre isso ..

Update:
Recentemente eu encontrei uma outra diferença entre usar temporizador contra Thread.sleep (). Suponha que a hora do sistema atual é 11:00. Se reverter a hora do sistema para 10:00, por algum motivo, o temporizador irá parar a execução da tarefa até que tenha alcançado 11:00, enquanto Thread.sleep () método seria continuar a executar a tarefa sem obstáculos. Este pode ser um grande tomador de decisão para decidir o que usar entre estes dois.

Foi útil?

Solução

A vantagem de TimerTask é que ele expressa sua intenção muito melhor (isto é, código de legibilidade), e já tem a cancelar () recurso implementado.

Note que ele pode ser escrito de uma forma mais curta, bem como o seu próprio exemplo:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);

Outras dicas

Timer / TimerTask também leva em conta o tempo de execução de sua tarefa, por isso vai ser um pouco mais preciso. E lida melhor com multithreading problemas (tais como evitar impasses etc.). E, claro, geralmente é melhor usar o código padrão bem testado em vez de alguma solução caseira.

Eu não sei por que, mas um programa que eu estava escrevendo estava usando temporizadores e é tamanho da pilha foi aumentando constantemente, uma vez que eu mudei para thread / sono problema resolvido.

Se você enfiar obter exceção e é morto, que é um problema. Mas TimerTask vai cuidar dela. Ele será executado independentemente da falha na execução anterior.

Há um argumento decisivo contra a gerir esta tarefa usando tópicos Java e método sleep. Você está usando while(true) para ficar indefinidamente no circuito e hibernar o segmento, colocando a dormir. E se NewUploadServer.getInstance().checkAndUploadFiles(); ocupa alguns recursos sincronizados. Outros tópicos serão incapazes de acessar esses recursos, a fome pode acontecer que pode abrandar o seu aplicativo inteiro. Estes tipos de erros são difíceis de diagnosticar e é uma boa idéia para evitar a sua existência.

O outro aproach desencadeia a execução do código que importa para você, ou seja, NewUploadServer.getInstance().checkAndUploadFiles(); chamando o método run() do seu TimerTask, deixando outros segmentos usando os recursos no entretanto.

A partir do Timer documentação :

Java 5.0 introduziu o pacote java.util.concurrent e um dos utilitários de simultaneidade aí é o que ScheduledThreadPoolExecutor é um pool de threads para tarefas repetidamente execução a uma determinada taxa ou demora. É efetivamente um substituto mais versátil para o Timer / combinação TimerTask, pois permite que vários segmentos de serviços, aceita várias unidades de tempo, e não requer subclassificação TimerTask (Basta implementar Runnable). Configurando ScheduledThreadPoolExecutor com um fio torna equivalente ao temporizador.

Assim Prefere ScheduledThreadExecutor vez de Timer:

  • Timer utiliza única discussão de fundo que é usado para executar todas as tarefas do temporizador, sequencialmente. Então tarefas devem concluir rapidamente então ele irá atrasar a execução de tarefas subsequentes. Mas no caso de ScheduledThreadPoolExecutor podemos configurar qualquer número de tópicos e também pode ter controle total, fornecendo ThreadFactory.
  • Timer pode ser sensível ao relógio do sistema, uma vez que faz uso do método Object.wait(long). Mas ScheduledThreadPoolExecutor não é.
  • exceções de tempo de execução jogados dentro TimerTask vai matar esse segmento particular, tornando assim Temporizador morto onde, como podemos lidar com isso em ScheduledThreadPoolExecutor de modo que as outras tarefas não são afetados.
  • Timer fornece método cancel para terminar o temporizador e descartar quaisquer tarefas agendadas, no entanto, não interfere com a tarefa atualmente em execução e deixá-lo terminar. Mas se cronómetro está a funcionar como fio daemon então se nós cancelá-lo ou não, ela será cancelada assim que todas as threads do usuário são terminado a execução.

Temporizador vs Thread.sleep

Contador faz uso de Object.wait e é diferente de Thread.sleep

  1. A espera (wait) thread pode ser notificado (usando notify) por outro segmento, mas um sono não pode ser, ela só pode ser interrompida.
  2. Uma espera (e notificar) deve acontecer em um bloco sincronizado sobre o objeto do monitor enquanto o sono não.
  3. Durante o sono não libera o bloqueio, esperando irá liberar o bloqueio para o objeto de espera é chamado.

Eu acho que entendo o seu problema, eu estou vendo algo muito semelhante. I têm temporizadores que são recorrentes, alguns a cada 30 minutos e alguns a cada dois dias. Pelo que li e os comentários que vejo, parece que a coleta de lixo nunca vai ficar porque toda a tarefa nunca são completas. Gostaria de pensar que a coleta de lixo seria executado quando um temporizador está em repouso, mas eu não estou vendo isso e de acordo com a documentação que não.

Eu acho que desova novos tópicos concluída e permitir a coleta de lixo.

Alguém por favor me provar que estou errado, reescrever o que eu herdei vai ser uma dor.

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