fondo
Durante el desarrollo del proyecto, a menudo necesitamos realizar tareas periódicas. Puede ayudarnos a lograrlo bien a través de tareas de tiempo.
Comparemos varios marcos de tareas cronometrados de uso común:
Como se puede ver en la tabla anterior, el marco del horario de primavera tiene funciones completas y es simple y fácil de usar. El horario de primavera está completamente calificado para proyectos pequeños y medianos.
1. Programa de integración de SpringBoot
1.1 Agregar paquete de dependencia de Maven
Dado que el horario de primavera se incluye en el módulo básico de Spring-Boot-Starter, no se requieren dependencias adicionales.
<pendencies> <Spendency> <MoupRid> org.springframework.boot </proupId> <artifactID> spring-boot-starter </artifactid> </pendency> <pendency> <MoupRupid> org.springFrameWork.Boot </groupId> <AtifactId> </pendency> </dependencias>
1.2 Clase de inicio, agregue la anotación de inicio
Agregar la anotación @EnablesCheduling a la clase de entrada o configuración SpringBoot puede habilitar las tareas de tiempo.
@Habilscheduling@springbootapplicationpublic class scheduleApplication {public static void main (string [] args) {springapplication.run (schedulePplication.class, args);}}1.3. Agregar tareas cronometradas
Daremos ejemplos de los tres programadores de tareas del horario de primavera.
1.3.1 expresiones cron
Similar a las reglas de definición de tiempo de expresión Cron bajo Linux. Una expresión cron consta de 6 o 7 espacios separados por campos de tiempo, como se muestra en la figura a continuación:
Expresiones comunes:
Toma una castaña:
Agregue un método Work (), que se ejecuta cada 10 segundos.
Nota: Cuando el tiempo de ejecución del método excede la frecuencia de programación de tareas, el planificador se ejecutará en el siguiente ciclo.
Por ejemplo: Suponiendo que el método Work () comienza a ejecutarse en el segundo 0 y el método se ejecuta durante 12 segundos, entonces la próxima vez que se ejecute el método Work () es el 20º segundo.
@ComponentPublic Class myTask {@scheduled (cron = "0/10 * * * * *") public void work () {// Logic de ejecución de tareas}}1.3.2 Tareas de intervalo fijo
El siguiente tiempo de ejecución de la tarea se calcula a partir de la hora final de la última ejecución de la tarea del método. E iniciar la ejecución periódica de las tareas con esta regla.
Toma una castaña:
Agregue un método Work () y ejecútelo cada 10 segundos.
Por ejemplo: Suponga que el método Work () comienza a ejecutarse en el segundo 0 y el método se ejecuta durante 12 segundos, luego la próxima vez que se ejecute el método Work () es el 22.
@Scheduled (fixeddelay = 1000*10) public void work () {// Logic de ejecución de tareas}1.3.3 Tareas de frecuencia fija
Ejecute tareas en la frecuencia especificada e inicie la ejecución periódica de la programación con esta regla.
Toma una castaña:
Agregue un método Work (), que se ejecuta cada 10 segundos.
Nota: Cuando el tiempo de ejecución del método excede la frecuencia de programación de tareas, el programador ejecutará la siguiente tarea inmediatamente después de ejecutar el método actual.
Por ejemplo: Suponga que el método Work () comienza a ejecutarse en el segundo 0 y el método se ejecuta durante 12 segundos, luego la próxima vez que se ejecute el método Work () es el 12º segundo.
@Scheduled (fijado = 1000*10) public void work () {// Logic de ejecución de tareas}2. Configure el grupo de subprocesos de TaskScheduler
En proyectos reales, nuestro sistema puede definir múltiples tareas de tiempo. Entonces múltiples tareas de tiempo se pueden realizar de forma independiente y en paralelo.
Al observar el org.springframework.scheduling.config.scheduledTaskregistrar Código fuente, se encuentra que Spring creará un grupo de subproceso único de forma predeterminada. Esto puede ser fatal para nuestra multitarea. Cuando múltiples tareas se ejecutan simultáneamente (o deben ejecutarse al mismo tiempo), el programador de tareas experimentará la deriva del tiempo y el tiempo de ejecución de la tarea será incierto.
Profected void scheduleTasks () {if (this.taskscheduler == null) {this.localExecutor = ejecutors.newsinglethreadscheduledExeCutor (); this.TaskScheduler = nuevo concurrentTaskScheduler (this.localExecutor);} // omitir ...}2.1 Pool de hilo personalizado
Se agregó una clase de configuración para implementar la interfaz ProchulingConfigurer. Reescribe el método ConfigureTasks y establezca un grupo de subprocesos personalizado a través de TaskRegistrar.
@ConfigurationPublic Class Scheduleconfig implementa ProgramingConfigurer {@OverridePublic Void ConfigurETasks (ProgramedTaskRaristrar Taskregistrar) {Taskregistrar.SetsCheduler (TasKEXECUTOR ());}@bean (DestrationMethod = "apagado") Public Ejecutor Taskexecutor () {Return Ejecutores.newscheduledThreadPool (20);}}3. Problemas en aplicaciones prácticas
3.1 Problemas de inicio y cierre en aplicaciones web
Sabemos que los frijoles cargados o inicializados hasta la primavera se descargarán automáticamente (destruyen) cuando se detenga el servicio. Sin embargo, dado que los subprocesos son JVM-Level, si el usuario inicia un hilo en una aplicación web, el ciclo de vida de este hilo no será consistente con la aplicación web. Es decir, incluso si la aplicación web se detiene, el hilo aún no termina (muerte).
Solución:
1) El objeto actual se inicializa a través de la primavera
Cuando la primavera desinstale (destruye) una instancia, se llamará al método de destrucción de la instancia. Implementado mediante la implementación del método Destroy de la interfaz de dispositivos desechables. Cierre activamente el hilo en el método de destrucción.
@ComponentPublic Class myTask implementa desechableBean {@OverridePublic Void Destroy () lanza la excepción {// Cerrar el hilo o el grupo de hilos ThreadPoolTaskScheduler Scheduler = (ThreadPoolTaskScheduler) ApplicationContext.getBean ("Scheduler"); Scheduler.Shutdown ();} // omit ...}2) El objeto actual no se inicializa (se administra) hasta la primavera
Luego podemos agregar un oyente de contexto de servlet para cerrar activamente el hilo cuando se detenga el servicio de servlet.
La clase pública myTaskListenter implementa servletContextListener {@OverridePublic void contextDestroyed (servletContextEvent arg0) {// cierra hilo o grupo de hilos} // omitir ...}3.2 Problemas de implementación distribuidos
En proyectos reales, nuestro sistema generalmente se implementará en grupos, distribuidos o recuperados ante desastres. Entonces, las tareas de tiempo pueden tener problemas de concurrencia, es decir, la misma tarea se está ejecutando en varios servidores al mismo tiempo.
Solución (bloqueo distribuido):
1) Bloquear a través de la tabla de bases de datos
2) Middleware de caché
3) Implementado a través de Zookeeper
Resumir:
El horario de primavera nos proporciona un marco de tareas de tiempo simple, rápido, eficiente y estable. Sin embargo, es necesario considerar el ciclo de vida de los hilos y los problemas de implementación distribuidos.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.