2009-10-05 5 views
12

Предположим, у меня есть задача, которая вытягивает элементы из java.util.concurrent.BlockingQueue и обрабатывает их.ScheduledExecutorService с переменной задержкой

public void scheduleTask(int delay, TimeUnit timeUnit) 
{ 
    scheduledExecutorService.scheduleWithFixedDelay(new Task(queue), 0, delay, timeUnit); 
} 

Как я могу запланировать/перенести задачу, если частота может быть изменена динамически?

  • Идея заключается в том, чтобы принять поток обновлений данных и распространять их в пакетном режиме с графическим интерфейсом
  • Пользователь должен иметь возможность изменять частоту обновлений
+0

Мне непонятно, почему вы используете блокирующую очередь. если ваша очередь пуста. Я предполагаю, что запланированное задание будет заблокировано. это ваше намерение? это, вероятно, путает время планирования планировщика задач. –

+0

Я выбрал реализацию ArrayBlockingQueue, поскольку он должен быть потокобезопасным, уважать порядок FIFO и быть ограниченным. Даже если блок задач, он не должен путать планирование задач, если оно? – parkr

+0

Вы правы в использовании реализации BlockingQueue (фактически ScheduledThreadPoolExecutor использует его внутри). Однако почему вы распространяете свои обновления в GUI, используя таймер? Почему бы не сделать это в режиме реального времени? Есть ли слишком много обновлений? Вы беспокоитесь о том, как крутится нить? – Adamski

ответ

6

Я не думаю, что вы можете изменить фиксированную задержку. Я думаю, вам нужно использовать schedule(), чтобы выполнить одноразовый снимок и запланировать снова, как только он завершится (с измененным временем ожидания, если потребуется).

+1

Спасибо - я сделал «задержку» переменной экземпляра и добавил частный метод для выполнения следующих действий: while (! ExecutorService.isShutdown) {executorService.schedule (новая задача (очередь), задержка, TimeUnit.MILLISECONDS); } – parkr

1

Вы не должны использовать scheduleAtFixedRate, если вы пытаетесь обработать несколько задач очереди с определенным интервалом? scheduleWithFixedDelay будет ждать только указанной задержки, а затем выполнить одно задание из очереди.

В любом случае методы schedule* в ScheduledExecutorService вернут ссылку ScheduledFuture. Если вы хотите изменить скорость, вы можете отменить ScheduledFuture и перенести задачу с другой скоростью.

+0

scheduleWithFixedDelay (...) - создает и выполняет периодическое действие, которое активируется сначала после заданной начальной задержки, а затем с указанной задержкой между окончанием одного выполнения и началом следующего. Если какое-либо выполнение задачи встречает исключение, последующие исполнения подавляются. В противном случае задача будет прекращена только путем отмены или прекращения работы исполнителя. – parkr

+0

Можете ли вы привести пример кода отмены и перепланирования? Как насчет каких-либо обновлений? – parkr

0

scheduleWithFixedDelay (...) возвращает RunnableScheduledFuture. Чтобы перенести его, вы можете просто отменить и перенести его. Для того, чтобы перенести его, вы можете просто оберните RunnableScheduledFuture остроумие новый Runnable:

new Runnable() { 
    public void run() { 
     ((RunnableScheduledFuture)future).run(); 
    } 
}; 
22

Использование schedule(Callable<V>, long, TimeUnit) вместо scheduleAtFixedRate или scheduleWithFixedDelay. Затем убедитесь, что ваш Callable перепланирует себя или новый экземпляр Callable в какой-то момент в будущем. Например:

// Create Callable instance to schedule. 
Callable<Void> c = new Callable<Void>() { 
    public Void call() { 
    try { 
    // Do work. 
    } finally { 
    // Reschedule in new Callable, typically with a delay based on the result 
    // of this Callable. In this example the Callable is stateless so we 
    // simply reschedule passing a reference to this. 
    service.schedule(this, 5000L, TimeUnit.MILLISECONDS); 
    } 
    return null; 
    } 
} 

service.schedule(c); 

Такой подход позволяет избежать необходимости закрыть и воссоздать ScheduledExecutorService.

+0

Вместо 'Callable ' вы можете (должны?) Использовать 'Runnable'. – Thirler

+0

@Тирлер: Да, это справедливая точка. – Adamski

+0

Я не нахожу функцию 'schedule (Callable)' для ScheduledExecutorService. Только те, у которых есть все параметры. Не могли бы вы указать мне, где? Или, по крайней мере, зафиксировал пример, чтобы включить задержку 0. – jlanza

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