Pregunta

Estoy intentando transferir el código del uso de java temporizadores para usar scheduledexecutorservice

Tengo el siguiente 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;
         }
    }

}

¿Debo reemplazar las instancias de Timer en la clase A y la clase B con ScheduledExecutorService y hacer que las clases ATimerTask y BTimerTask se conviertan en una clase Runnable, por ejemplo

class B {

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

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

}

¿Es esto correcto?

EDITAR: Una de las principales motivaciones de la transferencia es que las excepciones de tiempo de ejecución lanzadas en TimerTask eliminan ese hilo y no se puede programar más. Quiero evitar el caso para que, incluso si tengo una excepción de tiempo de ejecución, el hilo debe seguir ejecutándose y no detenerse.

¿Fue útil?

Solución

NOTA: ¡La forma en que hizo esto filtrará hilos!

Si su clase B se mantendrá y cada instancia eventualmente se cerrará o cerrará o liberará, lo haría así:

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();
  }
}

Si no va a hacer este tipo de limpieza en cada instancia, entonces en su lugar haría esto:

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 que asigna en su código asigna un solo Thread . Si realiza muchas instancias de su clase B , a cada instancia se le asignará un Thread . Si no se recolecta la basura rápidamente, puede terminar con miles de subprocesos asignados (pero no utilizados, solo asignados) y puede bloquear todo el servidor, privando a cada proceso de la máquina, no solo su propia JVM. Lo he visto suceder en Windows y espero que también pueda suceder en otros sistemas operativos.

Un grupo de subprocesos en caché estático suele ser una solución segura cuando no tiene la intención de utilizar métodos de ciclo de vida en las instancias de objetos individuales, ya que solo mantendrá tantos subprocesos como se ejecutan y no uno para cada instancia que cree que aún no se haya recolectado basura.

Otros consejos

Se ve bien. Dependiendo de lo que esté haciendo, es posible que desee mantener el servicio de ejecutor como miembro para que pueda usarlo nuevamente. Además, puede recuperar un ScheduledFuture de los métodos scheduleXX (). Esto es útil porque puede llamar a get () para extraer cualquier excepción que ocurra en el hilo cronometrado de nuevo a su hilo de control para su manejo.

Actualmente no hay una buena manera de manejar tareas repetitivas en el marco de Ejecutores.

Realmente no fue diseñado con este caso de uso en mente, y no hay una forma realista de evitar tragar excepciones.

Si realmente debe usarlo para repetir tareas, cada programación debería verse así:

scheduler.scheduleWithFixedDelay(new Runnable() {
  public void run() {
     try {
       .. your normal code here...
     } catch (Throwable t) {
       // handle exceptions there
     }
  }
}, period, delay);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top