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 @Schedule
lugar. 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.Thread
em um ambiente baseado em Java EE / Servlet
Por último, mas não menos importante, nunca use diretamente java.util.Timer
e / ou java.lang.Thread
em 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 .