我正在使用Java,希望在我的应用程序中保持一个servlet的持续运行,但我不知道如何做到这一点。我的servlet有一个方法,每天从数据库中获取用户数量以及整个数据库的用户总数。因此,我希望为此保持servlet的持续运行。
我正在使用Java,希望在我的应用程序中保持一个servlet的持续运行,但我不知道如何做到这一点。我的servlet有一个方法,每天从数据库中获取用户数量以及整个数据库的用户总数。因此,我希望为此保持servlet的持续运行。
@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() {
// 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.
}
}
没错,就是这样。容器将自动获取和管理它。
ScheduledExecutorService
如果您的环境不支持EJB(即您不是使用真正的Java EE服务器,而是使用裸机Servlet容器,如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中使用java.util.Timer
和/或java.lang.Thread
。这是引发问题的根源。可以在此JSF相关答案中找到详细解释:使用计时器在JSF管理的bean中生成线程以进行定时任务。
run
方法中逃逸了异常,执行器就会默默地停止执行。这不是错误,而是一个特性。请阅读文档并通过搜索学习相关知识。 - Basil Bourqueorg.springframework.scheduling.concurrent.ScheduledExecutorTask
怎么样? - ACVscheduler.shutdownNow()
,那么就会发生这种情况。如果没有调用它,那么计划线程确实会继续运行。 - BalusC我建议使用像quartz这样的库来定期运行任务。Servlet到底是做什么的?它会发送给您一份报告吗?
实现两个类并在main
中调用startTask()
。
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();
}
}