Java 如何以固定的时间间隔运行后台作业方法?
我正在ApacheTomcat上使用JSP/Servlet。我必须每10分钟运行一次方法。我如何才能做到这一点?请阅读,它必须由 此外,您可以尝试从中使用Java,但不建议在JavaEE容器中使用,因为它会从容器中夺走对线程资源的控制。(使用ScheduledExecutorService的第一个选项是要走的路) 实现Java 如何以固定的时间间隔运行后台作业方法?,java,jakarta-ee,tomcat,servlets,background-process,Java,Jakarta Ee,Tomcat,Servlets,Background Process,我正在ApacheTomcat上使用JSP/Servlet。我必须每10分钟运行一次方法。我如何才能做到这一点?请阅读,它必须由 此外,您可以尝试从中使用Java,但不建议在JavaEE容器中使用,因为它会从容器中夺走对线程资源的控制。(使用ScheduledExecutorService的第一个选项是要走的路) 实现TimerTask的MyTask是一个实现Runnable接口的类,因此您必须用代码覆盖run方法: class MyTask extends TimerTask { pub
TimerTask
的MyTask
是一个实现Runnable
接口的类,因此您必须用代码覆盖run方法:
class MyTask extends TimerTask
{
public void run()
{
// your code here
}
}
由于您使用的是Tomcat,它只是一个基本的servletcontainer,所以不能使用EJB的
@Schedule
来实现这一点,这是JavaEE规范推荐的。最好的选择是来自Java1.5的Java.util.concurrent
包。您可以通过以下类似的方法触发此操作:
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeTask(), 0, 10, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
其中SomeTask
类如下所示:
public class SomeTask implements Runnable {
@Override
public void run() {
// Do your job here.
}
}
如果您实际使用的是一个真正的JavaEE容器,它支持EJB,并且都在em上(如Glassfish、JBoss AS、TomEE等),那么您可以使用EJB和方法。这样,容器就会担心线程的池化和破坏。然后,您只需要以下EJB:
@Singleton
public class SomeTask {
@Schedule(hour="*", minute="*/10", second="0", persistent=false)
public void run() {
// Do your job here.
}
}
请注意,通过这种方式,您可以继续透明地使用容器管理的事务(通常的方式(@PersistenceContext
等等),这在ScheduledExecutorService
中是不可能的-您必须手动获取实体管理器并手动启动/提交/结束事务,但在默认情况下,对于像Tomcat这样的裸体servletcontainer,您已经没有其他选项了
请注意,在假定的“终生”运行的JavaEEWeb应用程序中,绝不应使用计时器。它存在以下主要问题,不适合在Java EE中使用(引自):
定时器
对系统时钟的变化敏感,ScheduledExecutorService
则不敏感
Timer
只有一个执行线程,因此长时间运行的任务可能会延迟其他任务<代码>ScheduledExecutorService
可以配置任意数量的线程
TimerTask
中抛出的任何运行时异常都会杀死该线程,从而使Timer
失效,即计划任务将不再运行(直到重新启动服务器)ScheduledThreadExecutor
不仅捕获运行时异常,还允许您根据需要处理它们。引发异常的任务将被取消,但其他任务将继续运行好的,我知道了,我知道了。但是从哪里我必须调用这个方法。我必须在我的申请启动后立即启动。谢谢@BalusC。我在回答中明确提到了这一点。回答很好,谢谢@BalusC。但有一个问题:如果我需要更改通话间隔,我将如何修改调度器?e、 g.我有一些“int frequency”,可以由用户在webgui中设置,它表示两次运行之间的时间(以秒为单位)。
public class SomeTask implements Runnable {
@Override
public void run() {
// Do your job here.
}
}
@Singleton
public class SomeTask {
@Schedule(hour="*", minute="*/10", second="0", persistent=false)
public void run() {
// Do your job here.
}
}