ปัญหาของคุณคือคุณเข้าใจผิดวัตถุประสงค์ของไฟล์ เซิร์ฟเล็ต มีเจตนาที่จะดำเนินการกับคำขอ HTTP โดยไม่มีอะไรเพิ่มเติม คุณต้องการเพียงแค่งานเบื้องหลังที่ทำงานวันละครั้ง
EJB ใช้ได้ไหม ใช้@Schedule
หากสภาพแวดล้อมของคุณรองรับ EJB (เช่นเซิร์ฟเวอร์ Java EE จริงเช่น WildFly, JBoss, TomEE, Payara, GlassFish เป็นต้น) ให้ใช้@Schedule
แทน นี่คือตัวอย่างบางส่วน:
@Singleton
public class BackgroundJobManager {
@Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
}
@Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
}
@Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
}
@Schedule(hour="*", minute="*", second="*/5", persistent=false)
public void someFiveSecondelyJob() {
}
}
ใช่นั่นคือทั้งหมดจริงๆ คอนเทนเนอร์จะรับและจัดการโดยอัตโนมัติ
EJB ไม่พร้อมใช้งาน? ใช้ScheduledExecutorService
หากสภาพแวดล้อมของคุณไม่สนับสนุน EJB (เช่นคุณไม่ได้ใช้ไม่ได้เป็นเซิร์ฟเวอร์ Java EE จริง แต่เล่า servletcontainer เช่น Tomcat, ท่าเทียบเรือ, ฯลฯ ) ScheduledExecutorService
แล้วใช้ สิ่งนี้สามารถเริ่มต้นได้โดยไฟล์ServletContextListener
. นี่คือตัวอย่างการเริ่มต้น:
@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();
}
}
ตำแหน่งงานมีลักษณะดังนี้:
public class SomeDailyJob implements Runnable {
@Override
public void run() {
}
}
public class SomeHourlyJob implements Runnable {
@Override
public void run() {
}
}
public class SomeQuarterlyJob implements Runnable {
@Override
public void run() {
}
}
public class SomeFiveSecondelyJob implements Runnable {
@Override
public void run() {
}
}
อย่าคิดที่จะใช้java.util.Timer
/java.lang.Thread
ในสภาพแวดล้อมที่ Java EE / Servlet
สุดท้าย แต่ไม่น้อยไม่เคยใช้โดยตรงjava.util.Timer
และ / หรือjava.lang.Thread
ใน Java EE นี่คือสูตรสำหรับปัญหา คำอธิบายอย่างละเอียดสามารถพบได้ในคำตอบที่เกี่ยวข้องกับ JSF นี้ในคำถามเดียวกัน: หัวข้อวางไข่ใน JSF ถั่วจัดการสำหรับการใช้งานที่กำหนดเวลาการจับเวลา