我正在使用 Java,并且希望让 servlet 在我的应用程序中持续运行,但我不知道如何做到这一点。我的 servlet 有一个方法,可以每天给出数据库中的用户计数以及整个数据库中的用户总数。所以我想让 servlet 持续运行。

请您参考如下方法:

您的问题是您误解了 servlet 的目的。它的目的是对 HTTP 请求进行操作,仅此而已。您只需要一个每天运行一次的后台任务。

EJB 可用吗?使用@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. 
    } 
 
}  

是的,仅此而已。容器会自动拾取并管理它。

EJB 不可用?使用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/Servlet 的环境中

最后但并非最不重要的一点是,永远不要直接使用java.util.Timer和/或 java.lang.Thread在 Java EE 中。这是自找麻烦的根源。可以在同一问题的 JSF 相关答案中找到详细的解释:Spawning threads in a JSF managed bean for scheduled tasks using a timer .


评论关闭
IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!