小编典典

在Servlet JSP MVC网站的服务器端运行定期任务

java

我已经使用servlet和JSP开发了一个Web应用程序。我本身并没有使用任何框架,而是使用了自己的自制MVC框架。我正在使用MySQL作为后端。

我要执行以下操作:

  1. 每小时清理一次数据库中的一些数据
  2. 每隔15分钟在XML文件中的某处生成并存储有关数据的统计信息

问题是:当前,我的所有代码都是作为从客户端收到的请求而运行的。

如何在服务器端运行定期任务?

我现在有一个解决方案是在控制器的init函数中创建一个线程。还有其他选择吗?


阅读 188

收藏
2020-09-18

共1个答案

小编典典

您可以用来ServletContextListener在webapp启动时执行一些初始化。运行定期任务的标准Java
API方法是Timer和的组合TimerTask。这是一个启动示例:

public void contextInitialized(ServletContextEvent event) {
    Timer timer = new Timer(true);
    timer.scheduleAtFixedRate(new CleanDBTask(), 0, oneHourInMillis);
    timer.scheduleAtFixedRate(new StatisticsTask(), 0, oneQuartInMillis);
}

这两个任务看起来像这样:

public class CleanDBTask extends TimerTask {
    public void run() {
        // Implement.
    }
}

Timer但是,在Java
EE中不建议使用。如果任务抛出异常,则整个Timer线程将被杀死,您基本上需要重新启动整个服务器才能使其再次运行。该Timer也是在系统时钟的变化很敏感。

较新的和更强大的java.util.concurrent方式将是一个组合ScheduledExecutorService,只是一个Runnable。这是一个启动示例:

private ScheduledExecutorService scheduler;

public void contextInitialized(ServletContextEvent event) {
    scheduler = Executors.newSingleThreadScheduledExecutor();
    scheduler.scheduleAtFixedRate(new CleanDBTask(), 0, 1, TimeUnit.HOURS);
    scheduler.scheduleAtFixedRate(new StatisticsTask(), 0, 15, TimeUnit.MINUTES);
}

public void contextDestroyed(ServletContextEvent event) {
    scheduler.shutdownNow();
}
2020-09-18