2016-10-06 5 views
2

Мне нужно приостановить и возобновить запланированную задачу.Пауза и возобновление запланированной задачи

Я вижу много примеров кода для отмены() задачи, но мне нужно было бы возобновить ее/перезапустить. Я вижу предложения:

public void init(){ 
    scheduledTaskExecutor.getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true); 
} 
public void schedule(String id, Runnable task){ 
    ScheduledFuture<?> scheduledFuture = scheduledTaskExecutor.scheduleAtFixedRate(task); 
    runningTaskRegistry.put(id, task); 
} 

public void suspend(String id){ 
    ScheduledFuture<?> scheduledFuture = runningTaskRegistry.get(serviceName); 
    if(scheduledFuture != null){ 
     scheduledFuture.cancel(false); 
     try{ 
      scheduledFuture.get(); 
     } catch (InterruptedException | ExecutionException | CancellationException e){ 
      // I do not want the currently running task finishing after this point 
     } 
    } 
} 

... а затем мне нужно запланировать снова, а не перезагружать.

Является ли это ДЕЙСТВИТЕЛЬНО лучшим способом для этого?

+0

Как правило, да, перепланирование вашей задачи - лучший способ сделать это. Один взломан, который приходит на ум, использует [однопоточный исполнитель] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor--) и передавая ему задачу, которая ждет, пока условие паузы не станет ложным. – VGR

+0

Однопоточный исполнитель здесь не вариант: у меня есть десятки длительных процессов для запуска, а некоторые из них довольно длительные. – BTakacs

ответ

0

Я бы предпочел перепланировать через паузу и возобновление. Не только потому, что я не знаю, как это сделать, но и потому, что приостановленные задачи, вероятно, не будут выпускать свои потоки. За это время те потоки исполнителей блокируют и ничего не делают, даже если в очереди задач есть другие задачи.

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

+0

Я полностью согласен с тем, что блокирование потока исполнителей не является хорошим решением. Я просто подумал, что сам исполнитель может сделать это удаление во временный список, а затем перепланировать ... :-) Еще одним решением может быть создание Wrapper/Proxy вокруг Runnable и обработка паузы и возобновление там: не путем блокировки потока но игнорируя исходный запуск при приостановке :-) Это может привести к минимальным накладным расходам с минимальным шаблоном кода. – BTakacs

+0

@BTakacs Я думаю, что это действительно зависит от того, что ваши задачи будут делать, и если вы сможете повторно использовать промежуточные результаты. Как уже упоминалось ранее, я не знаю реализации, которая позволяет * эффективно * pausable и возобновляемые задачи, то есть потоки не только блокируются. Я предлагаю вам попробовать ['BlockingQueue'] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html), чтобы« припарковать »задачи и забрать их еще раз. Дайте мне знать, если вы хотите, чтобы я привел вам пример. – beatngu13

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