Pergunta

Eu estou tentando portar o código de java usando temporizadores para usando ScheduledExecutorService

Eu tenho o seguinte caso de uso

class A {

    public boolean execute() {
         try {
              Timer t = new Timer();
              t.schedule (new ATimerTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}


class B {

    public boolean execute() {
         try {
              Timer t = new Timer();
              t.schedule (new BTimerTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}

Eu deveria substituir instâncias Temporizador da classe A e classe B com ScheduledExecutorService e fazer a classe ATimerTask e BTimerTask a uma classe Runnable, por exemplo

class B {

    public boolean execute() {
         try {
              final ScheduledExecutorService scheduler = 
   Executors.newScheduledThreadPool(1);

              scheduler.scheduleWithFixedDelay (new BRunnnableTask(), period, delay);
         } catch (Exception e) {
              return false;
         }
    }

}

Está correto.

EDIT: Um dos principal motivação da portabilidade é desde exceções de tempo de execução jogado em TimerTask matar que um fio e não pode ser agendada ainda mais. Eu quero evitar o caso, para que Ieven se eu tiver exceção tempo de execução do segmento deve continuar a executar e não parada.

Foi útil?

Solução

NOTA: A maneira como você fez isso vai vazar tópicos

Se o seu B classe serão mantidas e cada instância acabará por ser fechado ou desligar ou lançado, gostaria de fazê-lo como este:

class B {
  final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

  public boolean execute() {
    try {
      scheduler.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
      return true;
    } catch (Exception e) {
      return false;
    }
  }

  public void close() {
    scheduler.shutdownNow();
  }
}

Se você não vai fazer este tipo de limpeza em cada instância, então eu iria ao invés fazer isso:

class B {
  static final ScheduledExecutorService SCHEDULER = Executors.newCachedThreadPool();

  public boolean execute() {
    try {
      SCHEDULER.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
      return true;
    } catch (Exception e) {
      return false;
    }
  }
}

Cada ExecutorService você alocar em seu código aloca uma única Thread. Se você faz muitas instâncias do seu B classe, em seguida, cada instância será atribuído um Thread. Se estes não se lixo coletado rapidamente, então você pode acabar com muitos milhares de threads alocados (mas não utilizados, apenas alocado) e você pode travar o seu servidor inteiro, morrendo de fome todos os processos na máquina, e não apenas o seu próprio JVM. Eu já vi isso acontecer no Windows e espero que pode acontecer em outro sistema operacional do bem.

Um pool de threads estática em cache é muitas vezes uma solução segura quando você não pretende usar métodos de ciclo de vida nas instâncias de objetos individuais, como você só vai manter tantos tópicos como são realmente executar e não um para cada instância que você cria que ainda não é lixo coletado.

Outras dicas

Parece ok. Dependendo do que você está fazendo, você pode querer manter o serviço executor em torno de como um membro para que você possa usá-lo novamente. Além disso, você pode obter uma volta ScheduledFuture dos métodos scheduleXX (). Isso é útil porque você pode chamar get () sobre ele para puxar todas as exceções que ocorrem na parte de trás fio cronometrado para seu segmento de controle para o manuseio.

Não há atualmente nenhuma boa maneira de lidar repetindo tarefas no âmbito executores.

Realmente não foi projetado com este caso de uso em mente, e não há nenhuma maneira realista para evitar engolir exceções.

Se você realmente deve usá-lo para repetir tarefas, cada agendamento deve ser algo como isto:

scheduler.scheduleWithFixedDelay(new Runnable() {
  public void run() {
     try {
       .. your normal code here...
     } catch (Throwable t) {
       // handle exceptions there
     }
  }
}, period, delay);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top