2012-02-01 6 views
1

У меня есть реализация Runnable, которая выполняет некоторую работу, которая может занять некоторое время, и я пытаюсь запланировать ее с помощью ScheduledThreadPoolExecutor с помощью метода scheduleAtFixedRate. Теперь я хочу, чтобы закрытие было изящным, что означает, что перед завершением задача должна быть полностью запущена. Я написал следующий код для выключения.Подождите, пока задача завершится до завершения в ScheduledThreadPoolExecutor

public void shutDown() throws Exception { 
    try { 
     LOG.info("Gracefully shutting down executor"); 
     executor.shutdown(); 
     if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) { 
      // cancels currently executing tasks. 
      LOG.info("Executor is still alive. Forcing executor thread pool to shut down"); 
      executor.shutdownNow(); 

      // Wait a while for tasks to respond to being cancelled 
      if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) { 
       LOG.fatal("Executor thread pool did not terminate"); 
       throw new Exception("Unable to shut down executor thread pool forcefully"); 
      } 
      LOG.info("Executor shut down."); 
     } 
    } catch (Exception e) { 
     LOG.error("Exception shutting down executor", e); 
     throw e; 
    } 
} 

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

Благодаря

Jitendra

+0

shutdown() должен сделать изящное окончание прав? в соответствии с документацией, shutdown() инициирует упорядоченное завершение работы, в котором выполняются ранее поставленные задачи, но новые задачи не будут приняты. Любая причина, по которой у вас есть другой код, связанный с awaitTermination (...); Вы хотите принудительно отключить, если он не завершен с определенным интервалом? – kosa

+0

Я думаю, что он только инициирует выключение и завершает работу, не блокирует и не ждет, пока потоки не будут закрыты. – RandomQuestion

+0

Мне нужен какой-то блокирующий вызов, чтобы я точно знал, когда задачи завершены – RandomQuestion

ответ

1

Самое простое решение - «перепроверить», так сказать. Я предлагаю вам использовать огромный период таймаута, который никоим образом не может быть превышен на время, необходимое для выполнения одной задачи, например:

// do you have tasks that can take more than 2^63 - 1 days to finish? :) 
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
0

Используйте shutdown() начать аккуратное завершение, а затем использовать awaitTermination(long, TimeUnit) ждать служб исполнителя, чтобы завершить закрытие.

0

Как было отмечено в комментарии executor.shutdown(), он не выдает никаких задач для выхода, а предотвращает принятие новых. Посмотрите в javadoc.

Еще один совет, если вы хотите, чтобы овладеть ваши задачи, как только они завершат, вы можете реализовать Callable<T> вместо Runnable, что это универсального типа и возвращает значение типа T. Тогда вы можете обернуть это Callable<T> в FutureTask<V> и отправьте это на ваш ScheduledThreadPoolExecutor. Затем вы можете выполнить свои задачи, как только они завершат свою работу и будут доступны. Таким образом, в коротком что-то вроде этого (обратите внимание, как только мы закончили загрузку планировщика с поставленными задачами, что это безопасно, чтобы закрыть его означает, что мы не даем какие-либо дополнительные задачи, которые будут представлены с тех пор):

ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(n); 
Callable<Integer> myTask = . . .; 
FutureTask<Integer> task = new FutureTask<Integer>(myTask); 
schedulerExecutor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); 
schedulerExecutor.shutdown(); 
Смежные вопросы