我正在使用Java,我想在应用程序中保持servlet不断运行,但我没有得到如何做。我的servlet有一种方法,可以每天从数据库以及整个数据库中用户的总数中提供用户计数。因此,我想为此保持servlet不断运行。

有帮助吗?

解决方案

您的问题是您误解了 servlet. 。目的是根据HTTP请求采取行动,仅此而已。您只需每天运行一次的背景任务。

EJB可用吗?利用 @Schedule

如果您的环境碰巧支持EJB(即Wildfly,Jboss,Tomee,Payara,Glassfish等真正的Java EE服务器,请使用 @Schedule 反而。这里有些例子:

@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.
    }

} 

是的,真的是全部。容器将自动拾取并管理它。

EJB不可用?利用 ScheduledExecutorService

如果您的环境不支持EJB(即您不使用真正的Java EE服务器,而是使用BareletContainer,例如Tomcat,Jetty等),请使用 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() {
        // 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.
    }

}

永远不要考虑使用 java.util.Timer/java.lang.Thread 在Java EE /基于Servlet的环境中

最后但并非最不重要的, 绝不 直接使用 java.util.Timer 和/或 java.lang.Thread 在Java Ee中。这是麻烦的秘诀。在同样的问题上,可以在此与JSF相关的答案中找到详尽的解释: 使用计时器的JSF托管BEAN中的产卵线程用于计划任务.

其他提示

我建议使用像石英这样的库来定期运行任务。 Servlet真正做什么?它给您发送报告吗?

实施两个类并致电 startTask()main.

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

在生产系统中,可能会运行多个非JEE容器。使用诸如Quartz Scheduler之类的Anot Enterprise调度程序,可以配置为任务Maamgememt的数据库。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top