Pregunta

Estoy usando Java y quiero seguir un servlet continua funcionando en mi solicitud, pero ahora no recibo cómo hacerlo. Mi servlet tiene un método que da cuentas de usuario desde una base de datos sobre una base diaria, así como el recuento total de los usuarios de toda la base de datos. Así que quiero mantener el servlet continuamente corriendo por ello.

¿Fue útil?

Solución

Su problema es que usted no entiende el propósito de la servlet . Se intented a actuar sobre las peticiones HTTP, nada más. Sólo desea una tarea en segundo plano que se ejecuta una vez en base diaria.

EJB disponibles? Utilice @Schedule

Si el entorno de pasar a EJB apoyo (es decir, un verdadero servidor Java EE como JBoss, JBoss, TomEE, Payara, GlassFish, etc), a continuación, utilizar @Schedule lugar. He aquí algunos 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 todo. El contenedor será automáticamente recogida y administrarla.

EJB disponible? Utilice ScheduledExecutorService

Si su entorno EJB no apoyo (es decir, no va a usar no es un verdadero servidor Java EE, pero un barebones servletcontainer como Tomcat, Espolón, etc), a continuación, utilizar ScheduledExecutorService . Esto puede ser iniciado por un ServletContextListener . He aquí un ejemplo patada de salida:

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

}

Cuando 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.
    }

}

No vuelvas a pensar en usar java.util.Timer / java.lang.Thread en un entorno basado en Java EE / servlet

Por último, pero no menos importante, no utilizar directamente java.util.Timer y / o java.lang.Thread en Java EE. Esta es la receta para los problemas. Una explicación elaborada se puede encontrar en esta respuesta JSF-relacionado en la misma pregunta: el desove hilos en un bean gestionado JSF para las tareas programadas usando un temporizador .

Otros consejos

Se recomienda usar una biblioteca como el cuarzo con el fin de ejecutar la tarea a intervalos regulares. ¿Qué hace el servlet realmente? Se le enviará un informe?

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

En un sistema de producción que puede tener múltiples envases no Jee en ejecución. Utilice anot programador de la empresa como el cuarzo planificador que puede ser configurado para utilizar una base de datos para maamgememt tarea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top