fundo
Durante o desenvolvimento do projeto, geralmente precisamos executar tarefas periódicas. Pode nos ajudar a alcançá -lo bem através de tarefas de tempo.
Vamos comparar várias estruturas de tarefas cronometradas comumente usadas:
Como pode ser visto na tabela acima, a estrutura do cronograma de mola possui funções completas e é simples e fácil de usar. O cronograma de primavera é totalmente qualificado para projetos pequenos e médios.
1. Cronograma de integração de trampolim
1.1 Adicionando pacote de dependência do Maven
Como o cronograma da primavera está incluído no módulo básico do Spring-Boot-Starter, não são necessárias dependências adicionais.
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependências>
1.2 Start Class, Adicione anotação de inicialização
Adicionar a anotação @enablescheduling à classe de entrada ou configuração de troca pode ativar as tarefas de tempo.
@Enablecheduling@springbootapplicationpublic Classe ScheduleAplication {public static void main (string [] args) {springapplication.run (scheduleapplication.class, args);}}1.3. Adicione tarefas cronometradas
Daremos exemplos dos três agendadores de tarefas da programação da primavera.
1.3.1 Expressões cron
Semelhante às regras de definição de tempo de expressão de Cron no Linux. Uma expressão de Cron consiste em 6 ou 7 espaços separados por campos do tempo, como mostrado na figura abaixo:
Expressões comuns:
Pegue uma castanha:
Adicione um método Work (), que é executado a cada 10 segundos.
Nota: Quando o tempo de execução do método exceder a frequência de agendamento de tarefas, o agendador será executado no próximo ciclo.
Por exemplo: assumindo que o método work () começa a ser executado no 0º segundo e o método é executado por 12 segundos, na próxima vez que o método work () for executado for o 20º segundo.
@ComponentPublic Classe MyTask {@Scheduled (Cron = "0/10 * * * * *") public void work () {// lógica de execução de tarefas}}1.3.2 Tarefas de intervalo fixo
O próximo tempo de execução da tarefa é calculado a partir do horário final da última execução de tarefas do método. E iniciar a execução periódica de tarefas com esta regra.
Pegue uma castanha:
Adicione um método work () e execute -o a cada 10 segundos.
Por exemplo: suponha que o método work () comece a ser executado no 0º segundo e o método seja executado por 12 segundos, e na próxima vez que o método work () for executado for o 22º segundo.
@Scheduled (fixolay = 1000*10) public void Work () {// Lógica de execução de tarefas}1.3.3 Tarefas de frequência fixa
Execute tarefas na frequência especificada e inicie a execução periódica da programação com esta regra.
Pegue uma castanha:
Adicione um método Work (), que é executado a cada 10 segundos.
Nota: Quando o tempo de execução do método exceder a frequência de agendamento de tarefas, o agendador executará a próxima tarefa imediatamente após a execução do método atual.
Por exemplo: suponha que o método work () comece a ser executado no 0º segundo e o método seja executado por 12 segundos, e na próxima vez que o método work () for executado for o 12º segundo.
@Scheduled (FIRLRATE = 1000*10) public void Work () {// Lógica de execução de tarefas}2. Configure o pool de threads do TaskScheduler
Em projetos reais, nosso sistema pode definir várias tarefas de tempo. Em seguida, várias tarefas de tempo podem ser executadas independentemente e em paralelo.
Observando o código-fonte org.springframework.scheduling.config.scheduledTaskReGistrar, verifica-se que a Spring criará um pool de thread único por padrão. Isso pode ser fatal para a nossa multitarefa. Quando várias tarefas forem executadas simultaneamente (ou precisam ser executadas ao mesmo tempo), o agendador de tarefas experimentará o tempo de tempo e o tempo de execução da tarefa será incerto.
Protected void scheduleTasks () {if (this.taskscheduler == null) {this.localexecutor = executores.newsinglethreadscheduledExecutor (); this.TaskScheduler = new ConcurrentTaskscheduler (this.localexecutor);} // omita ...}2.1 Pool de threads personalizado
Adicionado uma classe de configuração para implementar a interface SchedulingConfigurer. Reescreva o método ConfigureTasks e defina um pool de threads personalizado através do TaskReGistrar.
@ConfigurationPublic Class ScheduleConfig implementa o SchedulingConfigurer {@OverridePublic void ConfigureTasks (ScheduledTaskRegistrar TaskReGistrar) {TaskRegistrar.SetScheduler (Taskexecutor (); Executores.NewscheduledThreadpool (20);}}3. Problemas em aplicações práticas
3.1 Problemas de inicialização e desligamento em aplicativos da Web
Sabemos que os feijões carregados ou inicializados através da mola serão descarregados automaticamente (destruídos) quando o serviço for interrompido. No entanto, como os threads estão no nível da JVM, se o usuário iniciar um thread em um aplicativo da Web, o ciclo de vida deste thread não será consistente com o aplicativo da Web. Ou seja, mesmo que o aplicativo da web pare, o tópico ainda não termina (morte).
Solução:
1) O objeto atual é inicializado através da primavera
Quando a primavera desinstala (destrói) uma instância, o método de destruição da instância será chamado. Implementado implementando o método de destruição da interface DisposableBean. Feche ativamente o fio no método de destruição.
@ComponentPublic Classe myTask implementa DisposableBean {@OverridePublic void Destroy () lança Exceção {// Fechar o Thread ou Thread Pool ThreadPoolTaskScheduler Scheduler = (ThreadPoolTaskScheduler) ApplicationContext.GetBean ("Scheduler"); Schedule.shutDown ();2) O objeto atual não é inicializado (gerenciado) até a primavera
Em seguida, podemos adicionar um ouvinte de contexto de servlet para fechar ativamente o thread quando o serviço de servlet for interrompido.
classe pública mytasklistenter implementa servletContextListener {@OverridePublic void contextDestroyed (servletContextevent arg0) {// feche o thread pool} // omita ...}3.2 problemas de implantação distribuídos
Em projetos reais, nosso sistema geralmente será implantado em clusters, distribuído ou recuperação de desastres. Em seguida, as tarefas de tempo podem ter problemas de simultaneidade, ou seja, a mesma tarefa está em execução em vários servidores ao mesmo tempo.
Solução (bloqueio distribuído):
1) Bloquear através da tabela de banco de dados
2) Middleware de cache
3) Implementado através do Zookeeper
Resumir:
O cronograma da primavera nos fornece uma estrutura de tarefa simples, rápida, eficiente e estável. No entanto, é necessário considerar o ciclo de vida dos threads e problemas de implantação distribuídos.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.