如何在Tomcat中安排任务

27
我有一个部署在Tomcat上的Web应用程序。其中一组代码会检查数据库中特定的数据,然后根据这些数据向用户发送邮件。请问有什么方法可以在Tomcat中安排这个任务的时间表呢?
3个回答

28

实际上,在Tomcat中安排任务的最佳方式是使用ScheduledExecutorService。不应在J2E应用程序中使用TimeTask,这是不好的做法。

正确的示例:

创建一个与控制器包(servlet包)不同的包,并在该新包中创建一个新的Java类作为示例:

// your package
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class BackgroundJobManager implements ServletContextListener {

private ScheduledExecutorService scheduler;

@Override
public void contextInitialized(ServletContextEvent event) {
    scheduler = Executors.newSingleThreadScheduledExecutor();
   // scheduler.scheduleAtFixedRate(new DailyJob(), 0, 1, TimeUnit.DAYS);
    scheduler.scheduleAtFixedRate(new HourlyJob(), 0, 1, TimeUnit.HOURS);
   //scheduler.scheduleAtFixedRate(new MinJob(), 0, 1, TimeUnit.MINUTES);
   // scheduler.scheduleAtFixedRate(new SecJob(), 0, 15, TimeUnit.SECONDS);
}

@Override
public void contextDestroyed(ServletContextEvent event) {
    scheduler.shutdownNow();
 }

}

接下来,您可以创建其他 Java 类(每个日程表一个)如下:

public class HourlyJob implements Runnable {

@Override
public void run() {
    // Do your hourly job here.
    System.out.println("Job trigged by scheduler");
  }
}

享受吧 :)


5
像“……不应该在J2E应用程序中使用,这不是一个好的做法。”这样的声明,如果没有进一步的支持,也不是一个好的做法。 - zb226
1
ScheduledExecutorServicecron4j 相对较轻,如果您只有一个Tomcat实例,则可以很好地运行。然而,当您在集群或负载平衡环境中部署和运行应用程序时,该方法就不再适用了,因为您有可能导致每个实例同时运行相同的任务。像Quartz这样的解决方案已经具备了机制,以便只有一个正在运行的调度程序将执行任务。 - Pixelstix
@Pixelstix的评论真的应该成为答案。在我集群环境中实施某些东西之前,您已经帮我避免了头疼的问题! - Shawn

8

3

您可以使用监听器和cron4j

@WebListener
public class StartListener implements ServletContextListener {
    @Override
    public void contextInitialized(final ServletContextEvent servletContextEvent) {
        Scheduler scheduler = new Scheduler();
        scheduler.schedule("0 * * * *", new Task());
        scheduler.start();
        servletContextEvent.getServletContext().setAttribute("SCHEDULER", scheduler);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接