Seu problema é que você entendeu mal o propósito do servlet . Sua intenção é agir em solicitações HTTP, nada mais. Você quer apenas uma tarefa em segundo plano que é executada uma vez por dia.
EJB disponível? Usar@Schedule
Se acontecer de seu ambiente suportar EJB (ou seja, um servidor Java EE real, como WildFly, JBoss, TomEE, Payara, GlassFish, etc), use em seu @Schedulelugar. aqui estão alguns exemplos:
@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.
}
}
Sim, isso é realmente tudo. O contêiner irá retirá-lo e gerenciá-lo automaticamente.
EJB indisponível? UsarScheduledExecutorService
Se o seu ambiente não suportar EJB (ou seja, você não está usando um servidor Java EE real, mas um servletcontainer barebones como Tomcat, Jetty, etc), use ScheduledExecutorService. Isso pode ser iniciado por a ServletContextListener. Aqui está um exemplo inicial:
@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();
}
}
Onde as classes de trabalho são assim:
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 pense em usar java.util.Timer/ java.lang.Threadem um ambiente baseado em Java EE / Servlet
Por último, mas não menos importante, nunca use diretamente java.util.Timere / ou java.lang.Threadem Java EE. Esta é a receita para problemas. Uma explicação elaborada pode ser encontrada nesta resposta relacionada ao JSF na mesma pergunta: Gerando threads em um bean gerenciado JSF para tarefas agendadas usando um cronômetro .