Java Timer. Отсчет времени после старта потока

131
03 мая 2021, 23:10

Я использую Timer и устанавливаю таймер через метод shedule(), задавая повтор каждые N секунд. Но столкнулся с проблемой, мне необходимо запускать два таймера (а желательно и больше), так, чтобы отсчёт на каждом начинался ПОСЛЕ завершения работы run(), а не в момент его запуска.

Особенно это заметно, если один таймер тормозит другой из-за synchronized метода. И в результате один из таймеров повторно начинает свою работу не после N секунд от конца задачи, а через N-время работы второго таймера.

Как запускать таймер, после конца работы метода run()?

Код:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTimerTask(this), 2*1000, seconds*1000);
(+ также создается еще один таймер, с отличием в seconds)
public class MyTimerTask extends TimerTask {
    TemplateForBots bot;
    public MyTimerTask(TemplateForBots bot) {
        // TODO Auto-generated constructor stub
        this.bot = bot;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        locker(bot);
    }
    public static synchronized void locker(TemplateForBots bot) {
        System.out.println("I was locked by " + bot.getClass().getSimpleName() + " and it was " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        bot.setTaskForTimer();
    }
}
Answer 1

Для запуска периодических задач в Java наряду с таймерами, есть специальная абстракция ScheduledExecutorService, которая содержит методы schedule, scheduleAtFixedRate и scheduleWithFixedDelay все они возвращают ScheduledFuture - результат выполнения асинхронной задачи, абстракция для возможности отменить задачу или узнать о ее успешном выполнении, получить результат итд.

    ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
    s.scheduleWithFixedDelay(() -> {
        System.out.println(System.currentTimeMillis());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 0, 1, TimeUnit.SECONDS);

Код выше будет выводить время в консоль примерно раз в 3 секунды, 1 из задержки указанной при запуске таймера, еще 2 от Thread.sleep

READ ALSO
Как запустить несколько проектов на Eclipse?

Как запустить несколько проектов на Eclipse?

Мне необходимо запустить сразу несколько разных проекта на эклипсе, как это можно сделать?

156
Не запускается logstash

Не запускается logstash

Установил logstash по инструкции с оф сайта под windows https://wwwelastic

175
Параметризация метода

Параметризация метода

Как параметризуется метод при использовании Generic и в какой момент при параметризации методов в коде известны типы параметров

151
LinkedHashMap порядок добавления

LinkedHashMap порядок добавления

за счет чего сохраняется порядок добавления в LinkedHashMap?

150