I have a case, which is not the first time I have faced, and I would like a code review.
The issue is that I have a task, which must be run from time to time X (not exactly X, precision is desirable but not mandatory, an approximation is fine).
What I usually do is the following:
class Servicio implements Runnable {
private volatile boolean running = true;
@Override
void run() {
while(this.isRunning()) {
try {
// operaciones I/O y procesamiento
// Espero el tiempo X
Thread.sleep(1000);
} catch (InterruptedException ie) {
// no hago nada, que de vez en cuando el ciclo se ejecute
// de forma no muy precisa no es un problema.
} catch (otras excepciones que me interesa atrapar) {
// quizá stopRunning(), quizá no
// ya que las partes de I/O tienen retry polices,
// pero si por ejemplo recibo File Not Found o 404, no quiero seguir.
}
}
}
public synchronized void stopRunning() {
this.running = false;
}
public synchronized boolean isRunning() {
return this.running;
}
}
Additionally, stopRunning()
it can be called from another thread.
Ask:
What alternative design can I use? What are the advantages / disadvantages of this method compared to the proposed method?
If you plan to use pure Java, I would recommend using the framework
ExecutorService
via the interfaceScheduledExecutorService
to handle your tasks that run from time to time.If you can use a framework, I recommend Quartz as it allows you to create crons and run a task for each cron. It also allows you to run them synchronously. This means that, for a cron, if one task takes longer than the estimated time, the other tasks, instead of executing and possibly corrupting data, will stay in the queue and wait for the pending tasks to be released (or killed for some other reason). .