предисловие
Давайте посмотрим на сцену из интервью
Интервьюер: Я думаю, вы уже работали какое-то время, у вас есть какие-то стеки технологий, которые вы изучили более глубоко?
Вы: В настоящее время нет глубоких исследований, и он все еще находится в стадии возможности его использования.Я использовал xxx, и это определенно не проблема, чтобы иметь возможность работать!
Интервьюер: Использовался ли в проекте таймер и как вы его обычно используете?
Вы: Конечно, мы таймер на основе SpringBoot, он очень прост в использовании, просто аннотируйте его.
Интервьюер: Раз вы его использовали, давайте поговорим об использовании таймеров SpringBoot. Мы не задаем глубоких вопросов, и даже распределенные кластеры пока не рассматриваем. Мы рассматриваем только самые простые.
单线程模型
, то если моя запланированная задача выполняется каждые 5 секунд, но первая задача выполняется в течение 8 секунд, что произойдет со второй?Можете ли вы уточнить различные ситуации?
Вы: это... это действительно не считается
Интервьюер: Я еще не спрашивал принцип. Я просто задаю самые основные вопросы об использовании. В противном случае, сначала приходите сюда, а вы можете вернуться и дождаться уведомления.
Анализ использования таймеров
Я считаю, что каждый будет использовать таймер SpringBoot.Даже если вы им не пользуетесь, просто поищите его, и я верю, что вы сможете начать работу в течение 30 минут.Но на самом деле таймер Spring имеет три режима, а именно:fixedDelay
,cron
,fixedRate
.В чем разница между этими тремя?Давайте напишем демонстрацию таймера SpringBoot, чтобы испытать ее.
Метод фиксированной задержки
@Component
public class ScheduleHandle {
private final Logger log = LoggerFactory.getLogger(ScheduleHandle.class);
private List<Integer> index = Arrays.asList(8 * 1000, 3 * 1000, 6 * 1000, 2 * 1000, 2 * 1000);
private AtomicInteger atomicInteger = new AtomicInteger(0);
@Scheduled(fixedDelay = 3 * 1000)
public void fixedDelay() throws Exception {
int i = atomicInteger.get();
if (i < 5) {
Integer sleepTime = index.get(i);
log.info("第{}个任务开始执行,执行时间为{}ms", i, sleepTime);
Thread.sleep(sleepTime);
atomicInteger.getAndIncrement();
}
}
}
Самый простой способ, после завершения задачи интервал выполнения 3 секунды (как@Scheduled(fixedDelay = 3 * 1000)
), выполните следующее задание. Это легче всего понять, поэтому поставьте его первым. Если оно представлено диаграммой, его легче понять. А именно:
Приведенный выше вывод можно проверить с помощью выходного журнала.
2019-04-07 21:59:11.761 INFO 29372 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第0个任务开始执行,执行时间为8000ms
2019-04-07 21:59:22.772 INFO 29372 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第1个任务开始执行,执行时间为3000ms
2019-04-07 21:59:28.777 INFO 29372 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第2个任务开始执行,执行时间为6000ms
2019-04-07 21:59:37.783 INFO 29372 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第3个任务开始执行,执行时间为2000ms
2019-04-07 21:59:42.785 INFO 29372 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第4个任务开始执行,执行时间为2000ms
cron
@Scheduled(cron = "0/5 * * * * ? ")
public void cron() throws Exception {
int i = atomicInteger.get();
if (i < 5) {
Integer sleepTime = index.get(i);
log.info("第{}个任务开始执行,执行时间为{}ms", i, sleepTime);
Thread.sleep(sleepTime);
atomicInteger.getAndIncrement();
}
}
Потому что приведенный выше код настроен следующим образом:
//每5s执行一次
@Scheduled(cron = "0/5 * * * * ? ")
Таким образом, вы можете понять, что 5s - это цикл.Это эквивалентно принятию ванны в общежитии, потому что есть только одно положение для купания (одинарная нить), поэтому одновременно может войти только один человек, и тогда общежитие находится в дверь и каждые 5 секунд, чтобы увидеть, есть ли место. Если есть место, попросите следующего человека войти и принять душ.
-
На 5-й секунде заведующая общежитием взглянула и обнаружила, что первый одноклассник еще не вышел.
-
Во втором цикле то есть, на 10-й секунду, посмотрите еще раз. Если вы обнаружите, что уже есть вакансии, то спросите второго одноклассника, чтобы войти и промыть.
-
В третьем цикле, который длится 15 секунд, я еще раз посмотрел и обнаружил, что есть свободное место, и попросил третьего студента войти и помыться.
-
В четвертом цикле, который составляет 20 секунд, обнаруживается, что вакансий нет.
-
В пятом цикле, а это 25 секунд, выясняется, что есть вакансия, и тогда на стирку вызывается следующая, остальное не анализируется.
Используйте диаграмму, чтобы представить следующее:
Приведенный выше вывод можно проверить с помощью выходного журнала.
2019-04-07 22:15:30.002 INFO 29385 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第0个任务开始执行,执行时间为8000ms
2019-04-07 22:15:40.001 INFO 29385 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第1个任务开始执行,执行时间为3000ms
2019-04-07 22:15:45.001 INFO 29385 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第2个任务开始执行,执行时间为6000ms
2019-04-07 22:15:55.001 INFO 29385 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第3个任务开始执行,执行时间为2000ms
2019-04-07 22:16:00.001 INFO 29385 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第4个任务开始执行,执行时间为2000ms
fixedRate
@Scheduled(fixedRate = 5 * 1000)
public void fixedRate() throws Exception {
int i = atomicInteger.get();
if (i < 5) {
Integer sleepTime = index.get(i);
log.info("第{}个任务开始执行,执行时间为{}ms", i, sleepTime);
Thread.sleep(sleepTime);
atomicInteger.getAndIncrement();
}
}
Возьмем снова пример с купанием, но этот метод иcron
очень разные
Потому что приведенный выше код настроен следующим образом:
@Scheduled(fixedRate = 5 * 1000)
Вы можете понять, что заведующий общежитием заложил каждому студенту купание в течение 5 секунд, но первый студент зашел принять ванну, и на это ушло 8 секунд.
-
Второй одноклассник должен был войти на 5-й секунде, но когда первый одноклассник вышел, это было уже на 8-й секунде, поэтому общежитие спешно призвало второго одноклассника войти, чтобы угнаться за ходом времени.
-
Второй студент знал, что времени мало, и вышел через 3 секунды стирки.В это время заведующая общежитием обнаружила, что третий студент должен был войти на 10-й секунде, но сейчас дело дошло до 11-й секунды ( 8+3), затем Он быстро призвал третьего ученика войти.
-
Третий студент был в состоянии алкогольного опьянения, не мог не умыться 6 секунд.Когда он вышел, была уже 17-я секунда (8+3+6).Заведующий общежитием прищемил себе пальцы и обнаружил, что четвертый студент должна была быть 15-я секунда.Пора заходить.Оказывается сейчас 17 секунд,а время никого не ждет,поэтому я призываю четвертого одноклассника зайти и побыстрее умыться.
-
Четвертый студент вышел после 2 секунд мытье. Когда он вышел, глава общежития проверил время, и это было 19-го вторым.
"有原则"
Начальник общежития обнаружил, что пятый студент изначально планировал войти через 20 секунд, но сейчас было всего 19 секунд, и он не мог, поэтому дайте ему поиграть с мобильным телефоном 1 секунду на улице, а затем войдите через 20 секунд.
Используйте диаграмму, чтобы представить следующее:
Приведенный выше вывод можно проверить с помощью выходного журнала.
2019-04-07 22:18:44.814 INFO 29390 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第0个任务开始执行,执行时间为8000ms
2019-04-07 22:18:52.819 INFO 29390 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第1个任务开始执行,执行时间为3000ms
2019-04-07 22:18:55.824 INFO 29390 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第2个任务开始执行,执行时间为6000ms
2019-04-07 22:19:01.829 INFO 29390 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第3个任务开始执行,执行时间为2000ms
2019-04-07 22:19:04.816 INFO 29390 --- [pool-1-thread-1] com.toby.demo.job.ScheduleHandle : 第4个任务开始执行,执行时间为2000ms
напиши в конце
Feichao — это технический публичный аккаунт, в котором основное внимание уделяется принципам, исходному коду и навыкам разработки, оригинальному тематическому анализу исходного кода в аккаунте и реальному сражению принципов исходного кода в реальных сценах (ключевые моменты).Отсканируйте QR-код нижеОбратите внимание на Фей Чао, пусть те, кто должен строить ракеты, перестанут трахаться!