Executar uma TimerTask por vez

2 respostas
M

Pessoal, tenho o seguinte trecho de código:

timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        foo();
                    }
                }, 0, 60000);

Ou seja, de minuto em minuto preciso executar o método foo. Porém as vezes o método foo demora um pouco pra fazer seu trabalho.
Mas de acordo com a documentação:

Logo, as vezes se o método demorar, ele vai atrasar as próximas execuções e depois quando liberar, vai sair executando todas que ficaram atrasadas, certo?
Então pensei na seguinte solução:

...
    // Variável global
    boolean bloqueio = false;
    ...

                timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        if (bloqueio == false) {
                            foo();
                        }
                    }
                }, 0, 60000);
                    
                }

    ...

       void foo() {

        bloqueio = true;

        // operações...

       bloqueio = false;

     }

O que acham?

2 Respostas

R

Se você utilizar esta classe:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

e o método:
scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)

este tipo de problema não ocorrerá como ocorre na classe Timer.

S

marciosouzajunior:
Pessoal, tenho o seguinte trecho de código:

timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        foo();
                    }
                }, 0, 60000);

Ou seja, de minuto em minuto preciso executar o método foo. Porém as vezes o método foo demora um pouco pra fazer seu trabalho.
Mas de acordo com a documentação:

Logo, as vezes se o método demorar, ele vai atrasar as próximas execuções e depois quando liberar, vai sair executando todas que ficaram atrasadas, certo?

Não.
No javadoc daquele método diz "Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period. "
O método scheduleAtFixedRate garante que o start será dado no tempo certo. O que pode acontecer é que a execução N se subreponha à N-1 se ela ainda estiver rodando, e isso pode dar problema.
O método schedule garante o contrario. Que as execuções nunca se sobreponham, mas para isso, poderá haver um atrazo na execução.

Se vc pode executar duas invocações de “foco” simultaneamente, faça-o. Se não, use o outro método ou vc vai ter problemas. É comum, por exemplo se ha operações com bando de dados os dados comecarem a ficar corrompidos porque as chamadas não foram devidamente isoladas atomicamente.

Os métodos no ScheduleExecutor seguem o mesmo principio, e como já foi dito devem ser usados em vez do Timer

Criado 11 de janeiro de 2013
Ultima resposta 11 de jan. de 2013
Respostas 2
Participantes 3