Як запланувати виконання завдання з періодичними інтервалами?


76

Я пробував деякі коди для реалізації запланованого завдання і придумував ці коди.

import java.util.*;

class Task extends TimerTask {


    int count = 1;

    // run is a abstract method that defines task performed at scheduled time.
    public void run() {
        System.out.println(count+" : Mahendra Singh");
        count++;
    }
}

class TaskScheduling {

   public static void main(String[] args) {
       Timer timer = new Timer();


       // Schedule to run after every 3 second(3000 millisecond)
       timer.schedule( new Task(), 3000);   
   }
}

Мій результат:

1  :  Mahendra Singh

Я очікував, що компілятор надрукує серію Mahendra Singh з періодичним інтервалом у 3 с, але, незважаючи на очікування близько 15 хвилин, я отримую лише один результат ... Як це вирішити?


Кварцовий планувальник, щоб допомогти додатку Java планувати роботу / завдання, яке потрібно виконати у визначену дату та час, перевірити повний приклад цього
Tell Me How

1
Ці класи були замінені фреймворком Executors . Див. 7-й абзац JavaDoc для Timer.
Basil Bourque

Відповіді:


77

Використовуйте timer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task,
                                long delay,
                                long period)

Планує вказане завдання для повторного виконання з фіксованою ставкою, починаючи з зазначеної затримки. Подальші страти відбуваються приблизно через рівні проміжки часу, розділені зазначеним періодом.
При виконанні з фіксованою ставкою кожне виконання планується відносно запланованого часу виконання початкового виконання. Якщо виконання затримується з будь-якої причини (наприклад, вивезення сміття чи інша фонова діяльність), відбуватимуться дві або більше екзекуції швидко послідовно, щоб "наздогнати". У довгостроковій перспективі частота виконання буде точно такою, що відповідає зазначеному періоду (за умови, що системний годинник, що лежить в основі Object.wait (long), є точним).

Виконання з фіксованою ставкою підходить для періодичних дій, чутливих до абсолютного часу, таких як дзвінок щогодини на годину або проведення планового технічного обслуговування щодня в певний час. Це також доречно для повторюваних дій, де важливий загальний час виконання фіксованої кількості виконання, наприклад, таймер зворотного відліку, який тикає раз на секунду протягом десяти секунд. Нарешті, виконання з фіксованою швидкістю підходить для планування декількох повторюваних завдань таймера, які повинні залишатися синхронізованими відносно одного.

Параметри:

  • завдання - завдання, яке планується запланувати.
  • затримка - затримка в мілісекундах перед виконанням завдання.
  • період - час у мілісекундах між послідовним виконанням завдань.

Кидки:

  • IllegalArgumentException - якщо затримка від’ємна або затримка + System.currentTimeMillis () від’ємна.
  • IllegalStateException - якщо завдання вже було заплановано або скасовано, таймер скасовано або потік таймера припинено.

4
scheduleAtFixedRate не вирішує свою проблему отримання вихідних даних лише один раз.
James AN Stauffer

1
@ JamesA.N.Stauffer, йому потрібні результати неодноразово, не один раз.
st0le

3
Так, але повторення просто досягається додаванням третього аргументу - зміна методу не потрібна.
James AN Stauffer

2
@ st0le. розглянемо наступну аналогію. Той, хто питається, говорить: "Небо блакитне", ви говорите "Ні, трава зелена."
tony9099

Що робити, якщо ви хочете, щоб це був випадковий показник у певних верхніх і нижніх межах?
Hack-R

80

Перевага ScheduledExecutorServiceнадTimer

Я хочу запропонувати вам альтернативу Timerвикористанню - ScheduledThreadPoolExecutor , реалізація інтерфейсу ScheduledExecutorService . Він має деякі переваги перед класом Timer, згідно з "Java у паралельності":

A Timerстворює лише один потік для виконання завдань таймера. Якщо завдання таймера триває надто довго, точність синхронізації інших TimerTaskможе постраждати. Якщо повторне TimerTaskпланується запустити кожні 10 мс, а інше завдання таймера займає 40 мс, повторюване завдання (залежно від того, чи було воно заплановане із фіксованою швидкістю або фіксованою затримкою) викликається чотири рази швидко після послідовного запущене завдання завершує або повністю «пропускає» чотири виклики. Планові пули потоків вирішують це обмеження, дозволяючи надавати декілька потоків для виконання відкладених та періодичних завдань.

Інша проблема таймера полягає в тому, що він поводиться погано, якщо TimerTask видає неперевірений виняток . Також називається "витік нитки"

Потік таймера не вловлює виняток, тому неперевірений виняток, викинутий із TimerTaskтерміна, завершує потік таймера. Таймер також не відроджує нитку в цій ситуації; натомість помилково вважається, що весь таймер було скасовано. У цьому випадку тимчасові завдання, які вже заплановані, але ще не виконуються, ніколи не запускаються, і нові завдання не можна запланувати.

І ще одна рекомендація , якщо ви хочете створити свій власний сервіс планування, ви все одно можете бути в змозі скористатися перевагами бібліотеки, використовуючи DelayQueue, в BlockingQueueреалізацію , яка забезпечує функціональні можливості диспетчеризації ScheduledThreadPoolExecutor. A DelayQueueуправляє колекцією об'єктів із затримкою. Затримка пов’язана з часом затримки: DelayQueueдозволяє взяти елемент, лише якщо його затримка минула. Об'єкти повертаються із DelayQueueзамовленого до часу, пов'язаного з їх затримкою.


4
Інша проблема таймера полягає в тому, що при зміні системного годинника він псується з таймером
раджат,

15
public void schedule(TimerTask task,long delay)

Планує зазначене завдання для виконання після зазначеної затримки.

ти хочеш:

public void schedule(TimerTask task, long delay, long period)

Планує вказане завдання для повторного виконання із фіксованою затримкою , починаючи з зазначеної затримки. Подальші страти відбуваються приблизно через рівні проміжки часу, розділені зазначеним періодом.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.