Содержимое этой статьи синхронно обновлено на Github:GitHub.com/snail Climb/…, добро пожаловать звезда.
Много раз нам нужно установить регулярную задачу для системы, чтобы помочь нам что-то сделать, SpringBoot помог нам добиться хорошего, нам просто нужно напрямую использовать, конечно, вы не можете SpringBoot поставляется с обычными задачами, интеграция Quartz много раз также является хорошим выбором.
Эта статья не относится к содержанию интеграции SpringBoot с Quartz, а только демонстрирует, как использовать собственные задачи синхронизации SpringBoot.
Spring Schedule реализует временные задачи
Нам нужны только самые основные зависимости проекта SpringBoot, поэтому файлы конфигурации здесь публиковаться не будут.
1. Создайте запланированное задание
Мы используем@Scheduled
Аннотации могут легко создать временную задачу, которая описана в следующем коде.@Scheduled
Общие употребления, в том числе: выполнение фиксированного ставки, фиксированное выполнение задержки, исходное задержка выполнения и выполнение временных задач с использованием выражений CRON.
Выражение Cron: в основном он используется для выражения системы эксплуатации синхронного задания (TIMED TACED) для определения времени выполнения или частоты выполнения.
Рекомендуется онлайн-генератор выражений Cron:cron.qqe2.com/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* @author shuang.kou
*/
@Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
/**
* fixedRate:固定速率执行。每5秒执行一次。
*/
@Scheduled(fixedRate = 5000)
public void reportCurrentTimeWithFixedRate() {
log.info("Current Thread : {}", Thread.currentThread().getName());
log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date()));
}
/**
* fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。
*/
@Scheduled(fixedDelay = 2000)
public void reportCurrentTimeWithFixedDelay() {
try {
TimeUnit.SECONDS.sleep(3);
log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。
*/
@Scheduled(initialDelay = 5000, fixedRate = 5000)
public void reportCurrentTimeWithInitialDelay() {
log.info("Fixed Rate Task with Initial Delay : The time is now {}", dateFormat.format(new Date()));
}
/**
* cron:使用Cron表达式。 每分钟的1,2秒运行
*/
@Scheduled(cron = "1-2 * * * * ? ")
public void reportCurrentTimeWithCronExpression() {
log.info("Cron Expression: The time is now {}", dateFormat.format(new Date()));
}
}
На самом деле здесь есть яма по поводу fixedRate, если у нас такая ситуация: фиксированная скорость, установленная таймером одного из наших методов, выполняется каждые 5 секунд. Теперь этому методу необходимо выполнить следующие четыре задачи.Время выполнения четырех задач составляет: 6 с, 6 с, 2 с, 3 с. Как эти задачи будут выполняться по умолчанию (один поток)?
Напишем простую программу для проверки:
private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
private List<Integer> index = Arrays.asList(6, 6, 2, 3);
int i = 0;
@Scheduled(fixedRate = 5000)
public void reportCurrentTimeWithFixedRate() {
if (i == 0) {
log.info("Start time is {}", dateFormat.format(new Date()));
}
if (i < 5) {
try {
TimeUnit.SECONDS.sleep(index.get(i));
log.info("Fixed Rate Task : The time is now {}", dateFormat.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
Результат работы программы следующий:
Start time is 20:58:33
Fixed Rate Task : The time is now 20:58:39
Fixed Rate Task : The time is now 20:58:45
Fixed Rate Task : The time is now 20:58:47
Fixed Rate Task : The time is now 20:58:51
Это должно быть хорошо понято, посмотрев на схематическую диаграмму запущенной задачи ниже.
Если мы изменим этот метод на параллельный, результаты будут другими.
2. Добавить в класс запуска@EnableScheduling
аннотация
В SpringBoot нам нужно только добавить класс запуска@EnableScheduling
Запланированное задание можно запустить.
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3. Пользовательский пул потоков для выполнения запланированной задачи
по умолчанию,@Scheduled
Задачи по умолчанию выполняются в размере пула потоков, созданном для Spring, который вы можете добавить в@Scheduled
Добавьте следующий код в метод аннотации для проверки.
logger.info("Current Thread : {}", Thread.currentThread().getName());
Вы обнаружите, что запланированная задача с приведенным выше кодом будет выводить каждый раз при запуске:
Current Thread : scheduling-1
Если нам нужно выполнение пользовательского пула потоков, нам нужно только добавить новую реализациюSchedulingConfigurer
интерфейсconfigureTasks
Класс может быть, этот класс нужно добавить@Configuration
аннотация.
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
Имя текущего потока, выводимого вышеуказанным методом проверки, изменится.
4. @EnableAsync и @Async заставляют синхронизированные задачи выполняться параллельно
Если вы хотите, чтобы ваш код выполнялся параллельно, вы также можете передать@EnableAsync
и @Async
Эти две аннотации реализуют
@Component
@EnableAsync
public class AsyncScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(AsyncScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
/**
* fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。
*/
//@Async
@Scheduled(fixedDelay = 2000)
public void reportCurrentTimeWithFixedDelay() {
try {
TimeUnit.SECONDS.sleep(3);
log.info("Fixed Delay Task : The time is now {}", dateFormat.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Результат запуска программы следующий:reportCurrentTimeWithFixedDelay()
метод будет выполняться каждые 5 секунд, потому что мы сказали@Scheduled
Задачи выполняются в пуле потоков по умолчанию размера 1, созданном Spring.
Current Thread : scheduling-1
Fixed Delay Task : The time is now 14:24:23
Current Thread : scheduling-1
Fixed Delay Task : The time is now 14:24:28
Current Thread : scheduling-1
Fixed Delay Task : The time is now 14:24:33
reportCurrentTimeWithFixedDelay()
добавить метод@Async
Вывод после аннотации выглядит следующим образом:reportCurrentTimeWithFixedDelay()
Метод будет выполняться каждые 2 секунды.
Current Thread : task-1
Fixed Delay Task : The time is now 14:27:32
Current Thread : task-2
Fixed Delay Task : The time is now 14:27:34
Current Thread : task-3
Fixed Delay Task : The time is now 14:27:36
публика
Если вы хотите следить за моими обновленными статьями и делиться галантерейными товарами в режиме реального времени, вы можете подписаться на мой официальный аккаунт.
«Нападение на Java-интервью»:"Java Interview Assault" V2.0 PDF-версия, полученная из этого документа для интервью.публикаФоновый ответ"Блиц-интервью по Java"Получите это бесплатно!
Важные учебные ресурсы для Java-инженеров:Некоторые Java-инженеры обычно используют ключевые слова для фонового ответа общедоступной учетной записи учебных ресурсов."1"Вы можете получить его бесплатно без каких-либо уловок.