[Фэй Чао] Если оставить в стороне принцип, ты действительно умеешь пользоваться таймером?

Java задняя часть
[Фэй Чао] Если оставить в стороне принцип, ты действительно умеешь пользоваться таймером?

предисловие

Давайте посмотрим на сцену из интервью

Интервьюер: Я думаю, вы уже работали какое-то время, у вас есть какие-то стеки технологий, которые вы изучили более глубоко?

Вы: В настоящее время нет глубоких исследований, и он все еще находится в стадии возможности его использования.Я использовал 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-код нижеОбратите внимание на Фей Чао, пусть те, кто должен строить ракеты, перестанут трахаться!