Il tuo problema è che fraintendi lo scopo del servlet . È destinato ad agire su richieste HTTP, niente di più. Vuoi solo un'attività in background che viene eseguita una volta su base giornaliera.
EJB disponibile? Uso@Schedule
Se il tuo ambiente supporta EJB (cioè un vero server Java EE come WildFly, JBoss, TomEE, Payara, GlassFish, ecc.), Usa @Schedule
invece. Ecco alcuni esempi:
@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ì, è davvero tutto. Il container lo ritirerà e lo gestirà automaticamente.
EJB non disponibile? UsoScheduledExecutorService
Se il tuo ambiente non supporta EJB (ovvero non stai utilizzando non un vero server Java EE, ma un servletcontainer barebone come Tomcat, Jetty, ecc.), Allora usa ScheduledExecutorService
. Questo può essere avviato da a ServletContextListener
. Ecco un esempio di kickoff:
@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();
}
}
Dove le classi di lavoro hanno questo aspetto:
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.
}
}
Non pensare mai di utilizzare java.util.Timer
/ java.lang.Thread
in un ambiente basato su Java EE / Servlet
Ultimo ma non meno importante, non utilizzare mai direttamente java.util.Timer
e / o java.lang.Thread
in Java EE. Questa è la ricetta per i guai. Una spiegazione elaborata può essere trovata in questa risposta correlata a JSF alla stessa domanda: generazione di thread in un bean gestito JSF per attività pianificate utilizzando un timer .