Vấn đề của bạn là bạn hiểu sai mục đích của servlet . Nó có ý định hoạt động trên các yêu cầu HTTP, không có gì hơn. Bạn chỉ muốn một nhiệm vụ nền chạy một lần hàng ngày.
EJB có sẵn? Sử dụng@Schedule
Nếu môi trường của bạn hỗ trợ EJB (tức là một máy chủ Java EE thực như WildFly, JBoss, TomEE, Payara, GlassFish, v.v.), thì hãy sử dụng @Schedule
thay thế. Dưới đây là một số ví dụ:
@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.
}
}
Vâng, đó thực sự là tất cả. Hộp chứa sẽ tự động nhận và quản lý nó.
EJB không khả dụng? Sử dụngScheduledExecutorService
Nếu môi trường của bạn không hỗ trợ EJB (tức là bạn không sử dụng máy chủ Java EE thực mà không phải là máy chủ servletcontainer cơ bản như Tomcat, Jetty, v.v.), thì hãy sử dụng ScheduledExecutorService
. Điều này có thể được bắt đầu bởi a ServletContextListener
. Đây là một ví dụ khởi động:
@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();
}
}
Nơi các lớp việc làm trông như thế này:
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.
}
}
Đừng bao giờ nghĩ đến việc sử dụng java.util.Timer
/ java.lang.Thread
trong môi trường dựa trên Java EE / Servlet
Cuối cùng nhưng không kém phần quan trọng, không bao giờ sử dụng trực tiếp java.util.Timer
và / hoặc java.lang.Thread
trong Java EE. Đây là công thức cho rắc rối. Có thể tìm thấy một lời giải thích phức tạp trong câu trả lời liên quan đến JSF này cho cùng một câu hỏi: Sinh ra các luồng trong bean được quản lý JSF cho các tác vụ đã lên lịch sử dụng bộ đếm thời gian .