How to run a background job method at fixed intervals? [duplicate]

本小妞迷上赌 提交于 2019-11-28 10:24:55

As you're on Tomcat, which is just a barebones servletcontainer, you can't use EJB's @Schedule for this which is recommended by Java EE specification. Your best bet is then the ScheduledExecutorService from Java 1.5's java.util.concurrent package. You can trigger this with help of a ServletContextListener like follows:

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

}

where the SomeTask class look like this:

public class SomeTask implements Runnable {

    @Override
    public void run() {
        // Do your job here.
    }

}

If you were actually using a real Java EE container with EJB support and all on em (like Glassfish, JBoss AS, TomEE, etc), then you could use a @Singleton EJB with a @Schedule method. This way the container will worry itself about pooling and destroying threads. All you need is then the following EJB:

@Singleton
public class SomeTask {

    @Schedule(hour="*", minute="*/10", second="0", persistent=false)
    public void run() {
        // Do your job here.
    }

} 

Note that this way you can continue transparently using container managed transactions the usual way (@PersistenceContext and so on), which isn't possible with ScheduledExecutorService — you'd have to manually obtain the entity manager and manually start/commit/end transaction, but you would by default already not have another option on a barebones servletcontainer like Tomcat anyway.

Note that you should never use a Timer in a supposedly "lifetime long" running Java EE web application. It has the following major problems which makes it unsuitable for use in Java EE (quoted from Java Concurrency in Practice):

  • Timer is sensitive to changes in the system clock, ScheduledExecutorService isn't.
  • Timer has only one execution thread, so long-running task can delay other tasks. ScheduledExecutorService can be configured with any number of threads.
  • Any runtime exceptions thrown in a TimerTask kill that one thread, thus making Timer dead, i.e. scheduled tasks will not run anymore (until you restart the server). ScheduledThreadExecutor not only catches runtime exceptions, but it lets you handle them if you want. Task which threw exception will be canceled, but other tasks will continue to run.
user1697575

Read on ScheduledExecutorService it has to be initiated by a ServletContextListener

public class MyContext implements ServletContextListener 
{
    private ScheduledExecutorService sched;

    @Override
    public void contextInitialized(ServletContextEvent event) 
    {
        sched = Executors.newSingleThreadScheduledExecutor();
        sched.scheduleAtFixedRate(new MyTask(), 0, 10, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) 
    {
        sched.shutdownNow();
    }
}

Also, you may try using the Java Timer from a ServletContextListener but it's not recommended in a Java EE container since it takes away control of the Thread resources from the container. (the first option with ScheduledExecutorService is the way to go).

Timer timer = new Timer("MyTimer");
MyTask t = new MyTask();

//Second Parameter is the specified the Starting Time for your timer in
//MilliSeconds or Date

//Third Parameter is the specified the Period between consecutive
//calling for the method.

timer.schedule(t, 0, 1000*60*10);

And MyTask that implements TimerTask is a class that implements the Runnable interface so you have to override the run method with your code:

class MyTask extends TimerTask 
{
  public void run() 
  { 
    // your code here
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!