Su problema es que no entiende el propósito del servlet . Tiene la intención de actuar sobre solicitudes HTTP, nada más. Solo desea una tarea en segundo plano que se ejecute una vez al día.
¿EJB disponible? Utilizar@Schedule
Si su entorno admite EJB (es decir, un servidor Java EE real como WildFly, JBoss, TomEE, Payara, GlassFish, etc.), utilice @Schedule
en su lugar. Aquí hay unos ejemplos:
@Singleton
public class BackgroundJobManager {
@Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
@Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
@Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
@Schedule(hour="*", minute="*", second="*/5", persistent=false)
public void someFiveSecondelyJob() {
// Do your job here which should run every 5 seconds.
}
}
Sí, eso es todo. El contenedor lo recogerá y gestionará automáticamente.
¿EJB no está disponible? UtilizarScheduledExecutorService
Si su entorno no es compatible con EJB (es decir, no está utilizando un servidor Java EE real, sino un contenedor de servlets básico como Tomcat, Jetty, etc.), utilice ScheduledExecutorService
. Esto puede ser iniciado por a ServletContextListener
. Aquí hay un ejemplo de inicio:
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Donde las clases de trabajo se ven así:
public class SomeDailyJob implements Runnable {
@Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
@Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
@Override
public void run() {
// Do your quarterly job here.
}
}
public class SomeFiveSecondelyJob implements Runnable {
@Override
public void run() {
// Do your quarterly job here.
}
}
Nunca piense en usar java.util.Timer
/ java.lang.Thread
en un entorno basado en Java EE / Servlet
Por último, pero no menos importante, nunca use directamente java.util.Timer
y / o java.lang.Thread
en Java EE. Esta es la receta para los problemas. Se puede encontrar una explicación detallada en esta respuesta relacionada con JSF sobre la misma pregunta: Generación de subprocesos en un bean administrado por JSF para tareas programadas usando un temporizador .