Twój problem polega na tym, że nie rozumiesz celu serwletu . Ma działać na żądaniach HTTP, nic więcej. Potrzebujesz tylko zadania w tle, które jest uruchamiane raz dziennie.
EJB jest dostępny? Posługiwać się@Schedule
Jeśli twoje środowisko obsługuje EJB (tj. Prawdziwy serwer Java EE, taki jak WildFly, JBoss, TomEE, Payara, GlassFish itp.), Użyj @Schedulezamiast tego. Oto kilka przykładów:
@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.
}
}
Tak, to naprawdę wszystko. Kontener automatycznie odbierze go i nim zarządza.
EJB niedostępny? Posługiwać sięScheduledExecutorService
Jeśli twoje środowisko nie obsługuje EJB (tj. Nie używasz nie prawdziwego serwera Java EE, ale serwletów szkieletowych, takich jak Tomcat, Jetty itp.), Użyj ScheduledExecutorService. Może to zostać zainicjowane przez ServletContextListener. Oto przykład wstępny:
@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();
}
}
Gdzie zajęcia wyglądają tak:
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.
}
}
Nigdy nie myśl o używaniu java.util.Timer/ java.lang.Threadw środowisku opartym na Java EE / Servlet
Wreszcie, nigdy nie używaj bezpośrednio java.util.Timeri / lub java.lang.Threadw Java EE. To recepta na kłopoty. Szczegółowe wyjaśnienie można znaleźć w tej związanej z JSF odpowiedzi na to samo pytanie: Odradzanie wątków w komponencie bean zarządzanym przez JSF dla zaplanowanych zadań przy użyciu timera .