2010-02-12 39 views
19

我开发了一个使用servlet和JSP的Web应用程序。我本身并没有使用任何框架,而是使用自己家酿的MVC框架。我使用MySQL作为后端。在服务器端运行servlet JSP MVC网站的定期任务

我要做到以下几点:

  1. 清理从数据库每小时一些数据
  2. 生成和有关数据存储统计数据在XML文件中的某个地方

每15分钟问题是:目前我所有的代码都是从客户端收到请求的结果运行的。

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

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

回答

41

您可以使用ServletContextListener在webapp启动时执行一些初始化。运行周期性任务的标准Java API方式将是TimerTimerTask的组合。这里有一个开球例如:

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方式将是ScheduledExecutorServiceRunnable的组合。这里有一个开球例如:

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(); 
} 
+2

只是要添加到BalusC的梦幻般的回答'ScheduledExecutorService'的'scheduleAtFixedRate'和'scheduleWithFixedDelay'方法将抑制未来的执行,如果在运行时遇到异常。所以请记住处理你的例外。 '如果任务的任何执行遇到异常,则后续执行被禁止.' – dvd 2012-06-01 00:49:28