java как сделать таймер [закрыт]

153
26 октября 2019, 08:30

Я хотел бы чтоб проще говоря у меня был таймер который после 1 минуты выполнял часть кода , допустим прибавлял к одной переменной еще 5 , и после этой минуты начал повторять это дело заново . В заранее спасибо

Answer 1

Приведенный ответ с использованием Timer тебе подойдет, но я бы порекомендовал бы использовать ExecutorService.

Вот как он используется:

public void start(){
    Task task = new Task();
    long delay1 = 1000, delay2 = 2, delay3 = 1, period1 = 2000, period2 = 3, period3 = 1;
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
    executorService.scheduleAtFixedRate(Task::taskRecruit, delay1, period1, TimeUnit.MILLISECONDS);
    executorService.scheduleAtFixedRate(task::taskHoliday, delay2, period2, TimeUnit.SECONDS);
    executorService.scheduleAtFixedRate(() -> System.out.println("lambda"), delay3, period3, TimeUnit.MINUTES);
}
...
class Task{
    void taskHoliday() {
        System.out.println("method");
    }
    static void taskRecruit() {
        System.out.println("static");
    }
}

Ссылка на оригинал ответа

Преимущества использования ExecutorService вместо Timer:

Ответ 1 (Оригинал ответа):

По мнению автора книги Java Concurrency in Practice:

  • Timer может быть чувствительным к изменениям системных часов, ScheduledThreadPoolExecutor - нет.
  • Timer имеет только один поток выполнения, поэтому длительное выполнение задачи может задержать выполнение других задач. ScheduledThreadPoolExecutor может быть настроен с любым количеством потоков. Кроме того, вы можете полностью контролировать созданные потоки, если хотите (используя ThreadFactory).
  • Ошибки (Exeptions), вызванные во время выполнения TimerTask, уничтожают единственный поток, что делает Timer мертвым :-( ... т.е. запланированные задачи больше не будут выполняться. ScheduledThreadExecutor не только перехватывает ошибки (Exceptions) во время выполнения, но и позволяет вам обрабатывать их, если хотите (переопределяя метод afterExecute из ThreadPoolExecutor). Задача, вызвавшая исключение, будет отменена, но другие задачи продолжат выполняться.

Ответ 2 (Оригинал ответа):

Из официальной документации Oracle на их странице о ScheduledThreadPoolExecutor:

ThreadPoolExecutor, который может дополнительно запланировать выполнение команд после заданной задержки или периодическое выполнение. Этот класс предпочтительнее, чем Timer, когда требуется несколько рабочих потоков или когда требуется дополнительная гибкость или возможности ThreadPoolExecutor (который расширяет этот класс).

ExecutorService/ThreadPoolExecutor или ScheduledThreadPoolExecutor это конечно же лучший выбор при работе с многопоточностью.

Плюсы ExecutorService перед Timer:

  1. Timer не может использовать преимущества доступных процессорных ядер в отличие от ExecutorService, особенно с несколькими задачами, использующими разновидности ExecutorService, такие как ForkJoinPool
  2. ExecutorService предоставляет совместный API, если вам нужна координация между несколькими задачами. Предположим, что вам необходимо отправить N рабочих задач и дождаться завершения всех из них. Вы можете легко достичь этого с помощью invokeAll API. Если вы хотите добиться того же с несколькими задачами таймера, это было бы не просто.
  3. ThreadPoolExecutor предоставляет лучший API для управления жизненным циклом потока.

Ссылка на оригинал вопроса/ответов

Answer 2

@since 1.3 есть java.util.Timer

TimerTask task = new TimerTask() {
    public void run() {
        System.out.println("task : " + new Date());
    }
};
Timer timer = new Timer("Timer");
long delay = 1000L;
timer.schedule(task, delay);

вышеприведенный код, в секции TimerTask.run() выполнится 1 раз через 1000мс

Если вам надо повторяющееся действие, с постоянной задержкой, необходимо у таймера вызывать

long peroid = 1000L;
timer.schedule (task, delay, peroid);

Если вам надо повторяющееся действие, с постоянной частотой, то для этого существует метод

long peroid = 1000L;
timer.scheduleAtFixedRate (task, delay, peroid);

Если Вам нужен таймер в Swing GUI потоке, то на этот случай тоже есть специальный класс javax.swing.Timer

int delay = 1000;
ActionListener listener = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("task : " + new Date());
    }
};
Timer timer = new Timer(delay, listener);
timer.start();

Чтобы операция повторялась необходимо добавить

timer.setRepeats(true);

@since 1.5 появился ScheduledExecutorService из пакета java.util.concurrent, который так же предназначен для выполнения периодических задач, но уже в многопоточной среде, он так же отлично подойдет для одного потока:

int corePoolSize = 1;
int delay = 1;
ScheduledExecutorService service = Executors.newScheduledThreadPool(corePoolSize);
service.schedule(() -> System.out.println("task : " + new Date()), delay, TimeUnit.SECONDS);
READ ALSO
Период у вещественных чисел

Период у вещественных чисел

Поддерживается ли в java бесконечные периодические дроби? Например, что будет при делении 86 на 30?

119
Сложный GridView / RecyclerView с картинками

Сложный GridView / RecyclerView с картинками

Есть данные в базе и с помощью их нужно создать GridView или RecyclerView не важно (суть одна что бы список был сортирован по категориям как на картинке...

168
JavaFx WebView, как увидеть ошибки в консоли

JavaFx WebView, как увидеть ошибки в консоли

Использую JavaFx WebView, не могу разобраться как увидеть ошибки, которые показываются в консоли браузера, если я открываю страницу через Google Chrome,...

205
Операции над примитивами

Операции над примитивами

Будет ли иметь смысл выражение: double d = 8 / 10; Я имею в виду, будет ли получаться десятичное число 08 P

228