2015-05-20 4 views
17

Возможно ли запланировать весенний метод обслуживания только один раз в точно указанное время? Например, текущее время составляет 2 вечера, но когда я нажимаю кнопку действия, я хочу, чтобы мой метод обслуживания начинался с 8 вечера. Я знаком с аннотацией @Scheduled, и я не уверен, как писать выражение cron, чтобы оно не запускалось периодически. Этот @Scheduled(cron = "0 0 20 * * ?") стреляет каждый день в 8 вечера.
Любые предложения?Задача Spring scheduling - запускать только один раз

+0

u можете использовать кварцевый планировщик :) –

ответ

16

Вы можете использовать одну из реализаций Spring TaskScheduler. Я привел нижеприведенный пример, который не требует слишком большой конфигурации (ConcurrentTaskScheduler, который обертывает однопоточный запланированный исполнитель).

Самый простой способ это один названный график, который принимает только Runnable и дату. Это вызовет задачу запускать один раз после указанное время. Все остальные методы позволяют планировать задачи для повторного запуска.

Подробнее о task execution & scheduling

Простой рабочий пример:

private TaskScheduler scheduler; 

Runnable exampleRunnable = new Runnable(){ 
    @Override 
    public void run() { 
     System.out.println("Works"); 
    } 
}; 

@Async 
public void executeTaskT() { 
    ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor(); 
    scheduler = new ConcurrentTaskScheduler(localExecutor); 

    scheduler.schedule(exampleRunnable, 
      new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text 
} 

... 

executeTaskT() //call it somewhere after the spring application has been configured 

Примечание:

Чтобы включить поддержку @Scheduled и @Async аннотации добавить @EnableScheduling и @EnableAsync к одному из ваших @Configuration классов


Update - отменить запланированное задание

метод графика TaskScheduler в возвращающем ScheduledFuture который является замедленного действия на результате подшипник, который может быть отменен.

Итак, чтобы отменить его, вам нужно сохранить дескриптор запланированной задачи (т. Е. Сохранить объект возврата ScheduledFuture).

Изменения в коде выше для отмены задачи:

  1. Объявите ScheduledFuture вне вашего метода executeTaskT. private ScheduledFuture scheduledFuture;

  2. Измените вызов, чтобы запланировать, чтобы сохранить обратный объект как таковой: scheduledFuture = scheduler.schedule(exampleRunnable, new Date(1432152000000L));

  3. Вызов отменить на объекте scheduledFuture где-то в коде boolean mayInterruptIfRunning = true; scheduledFuture.cancel(mayInterruptIfRunning);

+0

Это работает. Я расширил экземпляр ConcurrentTaskScheduler с исполнителем задачи управления потоками сервера, как этот «scheduler = new ConcurrentTaskScheduler (workManagerTaskExecutor, Executors.newSingleThreadScheduledExecutor())». Это тип 'org.springframework.scheduling.commonj.WorkManagerTaskExecutor' и предоставляется регистром сервера JNDI. – shx

+1

Отлично, работал для меня. btw, если требуется runnable с параметрами, вы можете написать метод, который принимает параметр и возвращает Runnable, а затем передать этот метод в планировщике с параметром scheduler.schedule (createRunnable (param1), new Date (1432152000000L)); –

+1

Является ли @Async обязательным для его достижения? – Angom

0

Для того, чтобы не создайте ScheduledExecutorService и ConcurrentTaskScheduler при каждом вызове метода удобно инициализировать TaskScheduler при создании службы, например

private final TaskScheduler taskScheduler = 
       new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10)); 

@Async не имеет смысла, так как мы просто запланировать задачу и выйти из метода.

Смежные вопросы