Как планировать выполнение задачи с периодическими интервалами?

Я пытался использовать некоторые коды для выполнения запланированной задачи и придумывал эти коды.

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 минут, я получаю только один результат... Как это решить?

Ответ 1

Использовать timer.scheduleAtFixedRate

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

Запланирует указанную задачу для повторного выполнения фиксированной ставки, начиная с указанной задержки. Последующие казни выполняются примерно через равные промежутки времени, разделенные на указанный период.
При исполнении с фиксированной ставкой каждое исполнение запланировано относительно запланированного времени выполнения первоначального выполнения. Если исполнение задерживается по какой-либо причине (например, сбор мусора или другая фоновая активность), два или более исполнения будут выполняться в быстрой последовательности, чтобы "догнать". В конечном счете, частота выполнения будет в точности совпадать с указанным периодом (при условии, что системные часы, лежащие в основе Object.wait(long), точны).

Исполнение с фиксированной ставкой подходит для повторяющихся действий, которые чувствительны к абсолютному времени, например, звонка в час каждый час в час или ежедневного планового обслуживания в определенное время. Также подходит для повторяющихся действий, когда важно общее время выполнения фиксированного количества исполнений, например таймер обратного отсчета, который тикает один раз в секунду в течение десяти секунд. Наконец, выполнение фиксированной скорости подходит для планирования нескольких повторяющихся задач таймера, которые должны оставаться синхронизированными относительно друг друга.

Параметры:

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

Броски:

  • IllegalArgumentException - если задержка отрицательная или задержка + System.currentTimeMillis() отрицательна.
  • IllegalStateException - если задание уже было запланировано или отменено, таймер был отменен или тайм-поток завершен.

Ответ 2

ScheduledExecutorService

Я хочу предложить вам альтернативу использованию таймера - ScheduledThreadPoolExecutor, реализация ScheduledExecutorService. Он имеет некоторые преимущества перед классом Timer (от "Java в Concurrency" ):

Таймер создает только один поток для выполнения задач таймера. Если задача таймера занимает слишком много времени для выполнения, может пострадать точность синхронизации других таймерных задач. Если запланированный запуск TimerTask запланирован каждые 10 мс, а другая задача таймера занимает 40 мс для запуска, повторяющаяся задача (в зависимости от того, была ли она запланирована с фиксированной скоростью или фиксированной задержкой), вызывается четыре раза подряд подряд после длительного завершающая задача завершается или полностью пропускает четыре вызова. Запланированные пулы потоков адресуют это ограничение, позволяя вам предоставлять несколько потоков для выполнения отложенных и периодических задач.

Еще одна проблема с Timer заключается в том, что он ведет себя плохо, если TimerTask выдает исключение. Нить Timer не вызывает исключения, поэтому исключенное исключение из TimerTask завершает поток таймера. Таймер также не воскрешает нить в этой ситуации; вместо этого он ошибочно предполагает, что весь таймер был отменен. В этом случае TimerTasks, которые уже запланированы, но еще не выполнены, никогда не запускаются, и новые задачи не могут быть запланированы. (Эта проблема называется "утечка потока" ).

И еще одна рекомендация, если вам нужно создать собственную службу планирования, вы все равно сможете воспользоваться библиотекой, используя DelayQueue, реализацию BlockingQueue, которая обеспечивает функциональность планирования ScheduledThreadPoolExecutor. DelayQueue управляет коллекцией объектов Delayed. A Delayed имеет время задержки, связанное с ним: DelayQueue позволяет вам взять элемент только в том случае, если его время задержки истекло. Объекты возвращаются из параметра DelayQueue, упорядоченного по времени, связанному с их задержкой.

Ответ 3

public void schedule(TimerTask task,long delay)

Запланирует указанную задачу для выполнения после указанной задержки.

вы хотите:

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

Запланирует указанную задачу для выполнения повторной фиксированной задержки, начиная с указанной задержки. Последующие казни выполняются примерно через регулярные интервалы, разделенные заданным периодом.

Ответ 4

Кварцевый планировщик также является решением, и, во-первых, вы выполняете класс Quartz Job.

Кварцевое задание определено, что вы хотите запустить

package com.blogspot.geekonjava.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
public class QuartzJob implements Job {
        public void execute(JobExecutionContext context)
                        throws JobExecutionException {
                JobKey jobKey = context.getJobDetail().getKey();
                System.out.println("Quartz" + "Job Key " + jobKey);
        }
}

Теперь вам нужно сделать Quartz Trigger

Существует два типа триггеров в Quartz

SimpleTrigger. Позволяет задать время начала, время окончания, интервал повторения.

Trigger trigger = newTrigger().withIdentity("TriggerName", "Group1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10).repeatForever()).build();

CronTrigger. Позволяет выражению unix cron указывать даты и       чтобы выполнить свою работу.

Trigger trigger = newTrigger()
                .withIdentity("TriggerName", "Group2")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build();

Класс планировщика связывает как Работа, так и Триггер и выполняет его.

Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);

Полный пример, который вы можете увидеть здесь

Ответ 5

Вы можете использовать Quartz

Ответ 6

timer.scheduleAtFixedRate( new Task(), 1000,3000); 

Ответ 7

Для этого у Java есть класс Timer и TimerTask, но что это такое?

  • java.util.Timer - это класс утилиты, который можно использовать для планирования поток, который будет выполнен в определенное время в будущем. Класс Java Timer может использоваться для планирования задачи, которая должна выполняться разом или для запуска на регулярной основе интервалы.
  • java.util.TimerTask - абстрактный класс, который реализует Runnable interface, и нам нужно расширить этот класс, чтобы создать собственный TimerTask, который может быть запланирован с использованием класса таймера Java.

Вы можете проверить полный учебник от GeekonJava

TimerTask timerTask = new MyTimerTask();

//running timer task as daemon thread

Timer timer = new Timer(true);

timer.scheduleAtFixedRate(timerTask, 0, 10*1000);