Я использую 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();
}
}
Для запуска периодических задач в 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
Продвижение своими сайтами как стратегия роста и независимости