Saltar al contenido

¿Cómo ejecutar una tarea en segundo plano en una aplicación web basada en servlet?

Te recomendamos que revises esta solución en un entorno controlado antes de enviarlo a producción, un saludo.

Solución:

Su problema es que no comprende el propósito del servlet. Tiene la intención de actuar sobre las solicitudes HTTP, nada más. Solo desea una tarea en segundo plano que se ejecute una vez al día.

EJB disponible? Utilizar @Schedule

Si su entorno es compatible con EJB (es decir, un servidor Java EE real como WildFly, JBoss, TomEE, Payara, GlassFish, etc.), utilice @Schedule en lugar de. Aquí hay unos ejemplos:

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

 

Sí, eso es realmente todo. El contenedor lo recogerá y gestionará automáticamente.

EJB no disponible? Utilizar ScheduledExecutorService

Si su entorno no es compatible con EJB (es decir, no está utilizando un servidor Java EE real, sino un servletcontainer básico como Tomcat, Jetty, etc.), utilice ScheduledExecutorService. Esto puede ser iniciado por un ServletContextListener. Aquí hay un ejemplo de lanzamiento:

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


Donde las clases de trabajo se ven así:

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.
    


Nunca pienses en usar java.util.Timer/java.lang.Thread en un entorno basado en Java EE / Servlet

Por último, si bien no menos importante, Nunca usar directamente java.util.Timer y/o java.lang.Thread en Java EE. Esta es la receta para los problemas. Se puede encontrar una explicación elaborada en esta respuesta relacionada con JSF sobre la misma pregunta: generar subprocesos en un bean administrado por JSF para tareas programadas usando un temporizador.

Sugeriría usar una biblioteca como cuarzo para ejecutar la tarea a intervalos regulares. ¿Qué hace realmente el servlet? ¿Te envía un informe?

Implementar dos clases y llamar startTask() en 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();
    

Nos puedes avalar nuestro análisis añadiendo un comentario y valorándolo te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *